Compare commits

13 Commits

Author SHA1 Message Date
Matsubaa 36c4ed7b62 feat: Enhance documentation and workflow clarity; add CI configuration for automated checks
CI / Format Check (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Tests (push) Has been cancelled
2026-05-23 18:30:44 -05:00
Matsubaa 2ecab4db12 feat: Update documentation to clarify Nix usage and enhance onboarding for non-Nix contributors 2026-05-23 18:17:47 -05:00
Matsubaa 94c7cadcd7 feat: Add packaging and deployment targets to architecture documentation; update roadmap with container packaging details and review policy 2026-05-23 18:15:31 -05:00
Matsubaa e20669e42a feat: Add project revision lifecycle details and clarify versioning model in documentation 2026-05-23 18:01:57 -05:00
Matsubaa 5ca022074d feat: Document personal data handling and lawful basis in architecture and open questions 2026-05-23 17:48:24 -05:00
Matsubaa 55d9db5c6c feat: Enhance architecture and roadmap documentation with material extensibility and persistence layer details 2026-05-23 17:40:20 -05:00
Matsubaa 941a9da928 feat: Update ROADMAP with personal data handling and user moderation features
- Added goals for defining personal data categories and retention obligations.
- Included exit criteria for user-level moderation, personal collections, and self-service data export.
- Expanded Phase 2 goals to include remote actor moderation and shareable block lists.

chore: Update flake.nix to specify main program

- Set the main program for the project in the flake configuration.

feat: Add issue templates for bug reports, feature requests, and questions

- Created structured templates to streamline issue reporting and feature suggestions.

docs: Add pull request template for consistent contributions

- Introduced a PR template to guide contributors on providing necessary information.

docs: Establish a Code of Conduct for community behavior

- Implemented a Code of Conduct to promote a respectful and inclusive environment.

docs: Create Diversity, Equity, and Inclusion (DEI) statement

- Outlined commitment to diversity and inclusion within the FeDIY community.

docs: Define Code Review Guidelines for constructive feedback

- Established guidelines to ensure respectful and effective code reviews.

docs: Implement Security Policy for vulnerability reporting

- Created a security policy detailing how to report vulnerabilities and our commitment to addressing them.
2026-05-23 17:26:28 -05:00
Matsubaa bf20d2a347 Enhance documentation structure and clarify project domain; add new directories for architecture, contracts, and extensions; update roadmap and open questions with resolved decisions and clarification plans. 2026-05-23 10:16:51 -05:00
Matsubaa c797a946c1 Enhance architecture documentation and add open questions; establish API-first architecture with bundled web UI as first-party client 2026-05-23 10:03:38 -05:00
Matsubaa 5794b593fa Refactor README and flake.nix for improved development environment setup; remove embedded Rust tooling references and add Cargo productivity tools 2026-05-23 09:56:42 -05:00
Matsubaa 6a825d1e83 Rename project to FeDIY and update related configurations and documentation 2026-05-23 09:53:29 -05:00
Matsubaa d61a91aac8 Add initial Cargo.lock file for dependency management 2026-05-23 09:53:20 -05:00
Matsubaa c97a9eb217 Enhance documentation with contributing guidelines, planning docs, and agent policies 2026-05-23 09:39:22 -05:00
31 changed files with 2402 additions and 106 deletions
@@ -0,0 +1 @@
disable = true
+40
View File
@@ -0,0 +1,40 @@
name: CI
on:
push:
branches:
- main
- planning
pull_request:
branches:
- main
- planning
jobs:
rustfmt:
name: Format Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- run: cargo fmt -- --check
clippy:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- run: cargo clippy --all-targets --all-features -- -D warnings
test:
name: Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- run: cargo test --verbose
+58
View File
@@ -0,0 +1,58 @@
---
name: Bug Report
about: Report something that isn't working
title: "[BUG] "
labels: bug
assignees: ''
---
## Describe the Bug
A clear and concise description of what the bug is.
## Steps to Reproduce
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
## Expected Behavior
What should happen instead?
## Actual Behavior
What actually happened?
## Environment
- **OS:** (e.g., Linux, macOS, Windows)
- **Rust version:** (run `rustc --version`)
- **How you built FeDIY:** (cargo build, nix build, etc.)
- **FeDIY version or commit:** (if applicable)
## Logs and Error Messages
```
Paste any relevant error messages, logs, or stack traces here.
```
## Screenshots or Videos
If applicable, add screenshots or video recordings to help explain the problem.
## Additional Context
Anything else that might be helpful?
## Possible Solution (Optional)
If you have thoughts on how to fix this, share them here!
---
**Thank you for reporting this!** We appreciate your help making FeDIY better.
+38
View File
@@ -0,0 +1,38 @@
---
name: Feature Request
about: Suggest an idea for FeDIY
title: "[FEATURE] "
labels: feature
assignees: ''
---
## Description
What would you like to see in FeDIY? Describe the feature or enhancement you're suggesting.
## Motivation
Why do you want this? What problem does it solve? How would it help you or the community?
## Example Use Case
Can you describe a specific scenario where this feature would be useful?
## Proposed Solution
Do you have an idea for how this could be implemented? (Feel free to skip this if you don't!)
## Alternatives
Are there other ways to solve this problem?
## Additional Context
Any other information that would be helpful? Links to related issues, discussions, or external resources?
---
**Thank you for sharing your idea!** Even if we can't implement everything, your feedback helps us understand what the community needs.
**Note:** Large features might be discussed further before work begins. Check [ROADMAP.md](../../docs/ROADMAP.md) and [OPEN_QUESTIONS.md](../../docs/OPEN_QUESTIONS.md) to see if this aligns with our current direction!
+30
View File
@@ -0,0 +1,30 @@
---
name: Question or Discussion
about: Ask a question or start a discussion about FeDIY
title: "[QUESTION] "
labels: question
assignees: ''
---
## Your Question
What would you like to know or discuss?
## Context
Help us understand the context of your question. What are you trying to do? What's your background with FeDIY?
## What Have You Tried?
Have you already looked somewhere for the answer? (Docs, existing issues, etc.)
## Additional Information
Anything else that might help us answer your question?
---
**Thank you for asking!** We're here to help. No question is too small or basic.
If you think this discussion should result in documentation changes, let us know—we'd love to improve our docs based on questions!
+40
View File
@@ -0,0 +1,40 @@
# Copilot Instructions for FeDIY
## Mission Context
FeDIY is intended to become a federated (ActivityPub) DIY project-hosting platform in Rust, inspired by communities like Ravelry and Instructables.
## Hard Constraint
Do not generate executable core project code.
This includes Rust code and other executable logic under:
- `src/`
- `tests/`
- Any runtime script or automation that becomes part of application behavior
## Allowed Help
You may assist with:
- Documentation
- Planning and architecture discussions
- Housekeeping and project management tasks
- Environment/tooling updates (including Nix files such as `flake.nix`, `default.nix`, and `shell.nix`)
## Delivery Process Defaults
- Use Red-Green TDD/BDD framing for planning and guidance.
- Assume GitHub Flow for branching and PR lifecycle.
- Support behavior-first test planning and review checklists.
## If Asked for Code
When a coding request is made, provide:
1. Links to primary sources (start with https://doc.rust-lang.org/book/).
2. A concise, paraphrased overview of the relevant concepts.
3. A step-by-step implementation checklist for a human developer.
Do not include code snippets or patches for executable core logic.
+45
View File
@@ -0,0 +1,45 @@
## Description
Please describe what this pull request does. What problem does it solve? What feature does it add?
**Closes:** #(issue number, if applicable)
## Type of Change
- [ ] Bug fix (non-breaking change that fixes an issue)
- [ ] New feature (non-breaking change that adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] Documentation update
- [ ] Refactoring (no functional change)
- [ ] Test improvement
## How Has This Been Tested?
How did you test your changes? Please describe:
- [ ] Existing tests pass
- [ ] Added new tests
- [ ] Tested manually (describe how)
- [ ] Other (describe)
## Checklist
- [ ] Code follows the project style (`cargo fmt`, `cargo clippy`)
- [ ] All tests pass (`cargo test`)
- [ ] New tests added for new functionality (if applicable)
- [ ] Documentation updated (if applicable)
- [ ] Commit messages are clear and follow conventions
- [ ] I have read the [Code of Conduct](../../CODE_OF_CONDUCT.md)
- [ ] My changes don't introduce security or accessibility issues
## Screenshots or Examples (Optional)
If your change affects the UI or user experience, add screenshots or examples here.
## Additional Notes
Anything else reviewers should know? Any trade-offs or decisions you made?
---
**Thank you for contributing!** We appreciate your effort. If you have any questions while preparing this PR, don't hesitate to ask in comments.
+51
View File
@@ -0,0 +1,51 @@
# Agent Policy for FeDIY
This project is building a federated (ActivityPub) DIY platform in Rust.
## Core Rule: Human-Written Executable Code
Agents MUST NOT write executable code for the core project. This includes (but is not limited to):
- Rust source files in `src/` and `tests/`
- Any scripts, binaries, or automation that execute as part of the app
- Generated code patches for runtime features
When asked for implementation help, agents should instead:
- Provide links to primary sources, especially:
- <https://doc.rust-lang.org/book/>
- <https://docs.rs/>
- <https://www.rfc-editor.org/rfc/rfc4287> (Atom reference, if needed)
- <https://www.w3.org/TR/activitypub/>
- Give a concise paraphrased overview of relevant concepts
- Offer checklists, architecture notes, and review guidance
- Suggest tests conceptually (without writing test code)
## Allowed Agent Work
Agents MAY help with non-executable project support work, including:
- Documentation authoring and editing
- Product and technical planning
- Issue triage, roadmap grooming, and housekeeping
- Environment and tooling management (for example `flake.nix`, `default.nix`, `shell.nix`, CI config)
- Dependency and configuration explanations
## Process Expectations
- Delivery workflow follows Red-Green TDD/BDD.
- Branching and collaboration follow GitHub Flow (short-lived branches from `main`, PR-first review cycle).
- Agents may support planning and documentation for this process, but must not produce executable core project code.
## Response Style for Coding Requests
If a user asks for executable Rust code, the agent should:
1. Decline to provide code for this repository's core project.
2. Link to the Rust Book section(s): <https://doc.rust-lang.org/book/>
3. Provide a paraphrased explanation of the relevant approach.
4. Offer a human-implementation checklist.
## Priority
If any default assistant behavior conflicts with this file, this file takes precedence for work in this repository.
+105
View File
@@ -0,0 +1,105 @@
# FeDIY Community Code of Conduct
## Our Commitment
FeDIY is dedicated to providing a welcoming, respectful, and inclusive environment for everyone—regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, education, socioeconomic status, nationality, personal appearance, race, religion, sexual identity and orientation, or any other dimension of human diversity.
We are committed to making participation in the FeDIY community a harassment-free experience for everyone. We value the diverse perspectives, backgrounds, and experiences that each member brings to our community.
## Our Standards
Examples of behavior that create a positive environment include:
- **Using inclusive, respectful language** — Avoid gendered, ableist, or discriminatory language. Use neutral pronouns (they/them) when uncertain.
- **Being welcoming and supportive** — Encourage newcomers; help them learn and grow. Remember that not everyone has the same background or expertise.
- **Actively listening** — Pay attention to others' perspectives and experiences, even (especially) when they differ from your own.
- **Acknowledging mistakes gracefully** — Apologize sincerely when you make an error and work to do better.
- **Focusing on what is best for the community** — We are all here to make FeDIY better. Constructive criticism and healthy debate strengthen our project.
- **Demonstrating empathy** — Try to understand others' experiences and challenges. Be patient and kind.
- **Recognizing diverse skill levels** — DIY communities thrive on curiosity and learning. Questions are welcome; condescension is not.
Examples of unacceptable behavior include:
- Harassment, intimidation, or discrimination of any kind
- Slurs, insults, or derogatory language
- Deliberate misgendering or use of rejected names
- Sexual harassment, unwanted sexual advances, or inappropriate sexual comments
- Threats of violence or violent language
- Abuse, mockery, or belittling of individuals or groups
- Doxxing (sharing private information without consent)
- Deliberate disruption of discussions or trolling
- Exclusionary behavior based on identity or background
- Pattern of aggressive behavior, even if individual comments seem minor
- Any conduct that violates laws or harms others
## Reporting Violations
If you experience or witness behavior that violates this code of conduct, we encourage you to report it. Your safety and comfort matter to us.
**How to Report:**
1. **For serious safety concerns:** Contact the project maintainers directly at [security@moturpin.com] or open a confidential GitHub Security Advisory.
2. **For other violations:** Report to the FeDIY maintainers via email at [conduct@moturpin.com] or by creating a confidential issue if available.
3. **In emergencies:** Contact local law enforcement or appropriate authorities.
**What to Include in Your Report:**
- A description of the incident
- Who was involved
- When and where it occurred
- Any witnesses
- Any relevant context or history
**Confidentiality:**
We will handle all reports with care and confidence. We will not name the complainant without their consent unless disclosure is necessary for safety. Reports will be reviewed promptly.
## Enforcement
The FeDIY maintainers will investigate all reports in good faith. Upon finding a violation, we may:
- Issue a warning to the person responsible
- Remove or edit comments/content
- Temporarily or permanently exclude the person from participation
- Report to appropriate authorities if necessary
We are committed to fair, proportional, and constructive enforcement. Our goal is accountability and community restoration, not punishment for its own sake.
## Appeal Process
If you believe a moderation decision was unfair, you may appeal to the project maintainers by providing additional context or new information. Appeals will be reviewed within 7 days.
## Our Responsibility
Project maintainers are responsible for:
- Clarifying the standards of acceptable behavior
- Responding promptly and fairly to reports
- Enforcing this code of conduct consistently
- Modeling inclusive, respectful behavior
- Being accessible and responsive to community concerns
- Regularly reviewing and updating this code of conduct
## Scope
This code of conduct applies to:
- All FeDIY project spaces (repositories, discussions, issue trackers, pull requests)
- Project communication channels (forums, chat, mailing lists, social media)
- In-person events, meetings, or conferences related to FeDIY
- Anywhere someone is representing FeDIY or its community
## Acknowledgments
This code of conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 2.1, which is widely used in open source communities and emphasizes inclusive, welcoming practices.
We also draw inspiration from CHAOSS (Community Health Analytics in Open Source Software) principles for measuring and improving community inclusion.
## Questions?
If you have questions about this code of conduct or how it applies to specific situations, please reach out to the maintainers. We're here to help.
---
**Last Updated:** May 2026
**Maintained by:** FeDIY Project Maintainers
+248 -7
View File
@@ -1,9 +1,250 @@
# Contributing
# Contributing to FeDIY
Thank you for considering contributing!
Welcome! We're thrilled you're interested in contributing to FeDIY. Whether you're a Rust expert, a DIY enthusiast, a designer, a writer, or just someone curious about federated projects, there's a place for you here.
- Please follow the project coding style and directory structure.
- Submit issues or pull requests for bugs, features, or improvements.
- Add tests for new features where possible.
- Ensure your code builds and passes tests before submitting.
- Contributions are licensed under CC BY-SA 4.0.
## Code of Conduct
Before you get started, please read our [Code of Conduct](CODE_OF_CONDUCT.md). We are committed to providing a welcoming, harassment-free environment for everyone. If you witness or experience behavior that violates the code of conduct, please report it.
## Diversity, Equity, and Inclusion
FeDIY is built on the belief that diverse perspectives make us stronger. We actively welcome contributions from people of all backgrounds, identities, and experience levels. See [DEI.md](DEI.md) for details on how we're building an inclusive community.
## Ways You Can Contribute
Not a code expert? No problem! We value all types of contributions:
### Code and Technical Work
- **Bug fixes:** Found a bug? Fix it! Start with issues labeled `bug`.
- **Features:** Want to implement something new? Check issues labeled `feature` or `help-wanted`.
- **Tests:** Improve test coverage or write new tests.
- **Performance improvements:** Optimize code or fix inefficiencies.
- **Rust learning:** If you're learning Rust, this is a great place to practice. We're happy to help with code review and guidance.
### Documentation and Writing
- **README improvements:** Is something confusing? Improve the docs!
- **API documentation:** Write clear, well-commented documentation for public APIs.
- **Tutorial and guides:** Help newcomers get started with FeDIY.
- **Blog posts or articles:** Share your experience with FeDIY (ask us before publishing to avoid duplication).
### Design and Accessibility
- **UI/UX improvements:** Suggest interface improvements or general enhancements.
- **Accessibility testing and review:** Test features with screen readers, keyboard navigation, and other assistive technologies. Report issues with WCAG 2.1 AA compliance. See [DEI.md](DEI.md) for our accessibility commitments.
- **Alt text and captions:** Help write or improve alt text for images, transcripts for videos, and captions for audio content.
- **Accessible documentation:** Improve docs for clarity, readability, and accessibility (plain language, good structure, proper heading hierarchy).
- **Accessibility tooling:** Develop or suggest tools to help creators make their content accessible (e.g., alt text helpers, caption templates).
- **Design for sensory differences:** Suggest improvements for people who are blind, low-vision, Deaf, hard-of-hearing, or have motor differences.
- **Architecture diagrams:** Help visualize how FeDIY works in multiple formats (visual diagrams, text descriptions, accessible charts).
### Community and Outreach
- **Issue triage:** Help organize and categorize issues.
- **Code review:** Review pull requests and provide constructive feedback.
- **Community discussions:** Participate in GitHub Discussions or forums.
- **Mentoring:** Help newer contributors get up to speed.
## Getting Started
### 1. Set Up Your Development Environment
Clone the repository and set up the development environment:
```bash
git clone https://github.com/moturpin/FeDIY.git
cd FeDIY
nix flake update # Update Nix dependencies
nix develop # Enter the development shell
cargo build # Build the project
cargo test # Run tests
```
**Note:** We use Nix flakes for reproducible development. If you don't have Nix installed, see our [README](README.md) for alternative setup instructions.
### 2. Choose Something to Work On
- **New to the project?** Look for issues labeled `good-first-issue` or `help-wanted`.
- **Want to learn?** Pick an issue that interests you and comment to let us know.
- **Have an idea?** Open a GitHub Discussion to get feedback before starting work.
- **Not sure?** Ask! Comment on an issue or start a discussion.
### 3. Create a Branch and Make Your Changes
We use GitHub Flow for branching:
```bash
git checkout -b feature/your-feature-name
# or: git checkout -b fix/issue-number-short-description
```
**Branch naming conventions:**
- `feature/feature-name` for new features
- `fix/issue-number-description` for bug fixes
- `docs/description` for documentation changes
- `refactor/description` for code cleanup
### 4. Write Commit Messages
Use clear, descriptive commit messages:
```
Summarize change in ~50 characters or less
Add more detailed explanation here if needed, wrapping around 72 characters.
If this closes an issue, mention it:
Closes #123
```
Follow the [conventional commits](https://www.conventionalcommits.org/) style when possible:
- `fix:` for bug fixes
- `feat:` for new features
- `docs:` for documentation changes
- `test:` for test changes
- `refactor:` for code cleanup
### 5. Testing and Quality
Before pushing, ensure your code is ready:
```bash
cargo fmt # Format code
cargo clippy # Run linter
cargo test # Run tests
cargo build --release # Build in release mode
```
All of these should pass before submitting a PR.
### 6. Push and Open a Pull Request
```bash
git push origin feature/your-feature-name
```
Then open a pull request on GitHub. Include:
- **Description:** What does this change do? Why?
- **Testing:** How did you test this? What should reviewers test?
- **Screenshots or examples** (if applicable)
- **Links to related issues** (e.g., "Closes #123")
We'll review your PR and provide feedback. Don't worry if we ask for changes—that's part of the process!
## Development Process
We follow Test-Driven Development (TDD) / Behavior-Driven Development (BDD):
### Red-Green-Refactor Cycle
1. **Red:** Write a test that fails (describes the desired behavior)
2. **Green:** Write minimal code to make the test pass
3. **Refactor:** Improve the code without changing behavior
See [WORKFLOW.md](docs/WORKFLOW.md) for more details on our development process.
## Code Style and Guidelines
- **Rust:** Follow [Rust API Guidelines](https://rust-lang.github.io/api-guidelines/). We use `rustfmt` for formatting.
- **Comments:** Write comments that explain *why*, not just *what*. The code itself shows what it does.
- **Type safety:** Leverage Rust's type system to prevent bugs. Prefer explicit types over type inference when it improves clarity.
- **Error handling:** Use Result/Option types appropriately. Avoid panicking except in truly unrecoverable situations.
- **Naming:** Use clear, descriptive names. Prefer `is_active` over `active` for booleans.
Run these before submitting:
```bash
cargo fmt --all
cargo clippy --all-targets -- -D warnings
```
## Human-Authored Core Code Policy
We are committed to human-authored, human-reviewed code for FeDIY's core:
- **Executable core code** (src/, tests/) must be written and understood by humans.
- **AI Assistants:** Agents may help with documentation, planning, housekeeping, and Nix environment management.
- **Implementation help:** When asking for coding guidance, you'll receive links to primary sources (especially the [Rust Book](https://doc.rust-lang.org/book/)), paraphrased explanations, and implementation checklists—not generated code.
This policy ensures code quality, maintainability, and learning. It doesn't prevent you from *using* AI tools; it just means you're responsible for understanding and authoring the final code.
## Architecture and Design
Before making large changes, review:
- [ARCHITECTURE.md](docs/ARCHITECTURE.md) — System design and component boundaries
- [ROADMAP.md](docs/ROADMAP.md) — Project phases and long-term direction
- [OPEN_QUESTIONS.md](docs/OPEN_QUESTIONS.md) — Unresolved design decisions
For significant changes, consider opening an issue or discussion first. This helps prevent duplicate work and ensures alignment with the project's direction.
## Pull Request Review Process
We value constructive, respectful code review:
- **Review timeframe:** We aim to provide initial feedback within 48 hours of a PR submission.
- **Expectations:** We may ask questions, suggest improvements, or request changes. This is normal!
- **Approval:** PRs need at least one approval from a maintainer before merging.
- **Passing checks:** All automated checks (formatting, linting, tests) must pass.
### For Reviewers
- Be respectful and constructive. Focus on the code, not the person.
- Explain *why* you're suggesting a change, not just that it should change.
- Acknowledge good work. Celebrate learning and growth.
- Ask questions rather than making demands.
## Licensing
All contributions are licensed under **CC BY-SA 4.0** (Creative Commons Attribution-ShareAlike 4.0). By contributing, you agree to this licensing.
- See [LICENSE](LICENSE) for details.
- This applies to all contributions (code, documentation, designs, etc.).
## Reporting Issues
Found a bug or have a feature request?
1. **Check existing issues** to avoid duplicates.
2. **Be clear and specific.**
- Include steps to reproduce for bugs.
- Explain your use case for features.
- Add error messages, logs, or screenshots if helpful.
3. **Include environment info:**
- OS and version
- Rust version (if relevant)
- How you built/ran FeDIY
## Security Issues
**Don't open public issues for security vulnerabilities!** See [SECURITY.md](SECURITY.md) for the responsible disclosure process.
## Getting Help
- **Stuck?** Open a GitHub Discussion or ask in an issue.
- **Questions about contribution?** Check [docs/WORKFLOW.md](docs/WORKFLOW.md) or ask.
- **Feedback on your PR?** Ask for help! Code review is collaborative.
- **Want to discuss design?** [OPEN_QUESTIONS.md](docs/OPEN_QUESTIONS.md) is a good place to start.
## Recognizing Contributors
We believe in recognizing contributions. Contributors are listed in:
- **GitHub:** Automatically in the repository's contributor graph
- **Release notes:** Major contributors mentioned in release announcements
- **Project documentation:** Long-term contributors highlighted
## Questions?
- **General questions:** Start a GitHub Discussion
- **Code of Conduct questions:** <conduct@moturpin.com>
- **Security issues:** <security@moturpin.com>
- **Other:** Open an issue and tag with `question`
---
Thank you for contributing! Together, we're building a federated DIY community that welcomes everyone. Happy coding!
Generated
+7
View File
@@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "fediy"
version = "0.1.0"
+1 -1
View File
@@ -1,5 +1,5 @@
[package]
name = "sample-rust-app"
name = "fediy"
version = "0.1.0"
edition = "2021"
+180
View File
@@ -0,0 +1,180 @@
# Diversity, Equity, and Inclusion Statement
FeDIY is committed to building a welcoming, inclusive community where everyone—regardless of background, identity, or experience level—can contribute to making DIY project sharing more accessible, federated, and community-driven.
## Our Commitment
We recognize that open source communities historically have barriers to participation and representation. We are committed to actively dismantling those barriers and building a project where:
- **Diverse voices are valued and heard.** We seek perspectives from people with different backgrounds, identities, expertise levels, and life experiences.
- **Newcomers and learners are welcomed.** DIY communities thrive on curiosity. Questions are encouraged, and we provide guidance to help people grow.
- **Accessibility is prioritized.** We design for multiple abilities (physical, cognitive, visual, hearing) and multiple ways of learning (visual, written, video, interactive).
- **Representation in leadership matters.** We actively work to ensure decision-making roles reflect our community's diversity.
- **Systemic barriers are addressed.** We regularly examine and remove practices that exclude or disadvantage specific groups.
## How We Live This Commitment
### 1. Inclusive Governance and Leadership
- **Open decision-making.** Major decisions are discussed transparently in GitHub issues, community forums, and public meetings.
- **Diverse maintainers.** We actively recruit and support maintainers from underrepresented groups in tech.
- **Mentorship and growth paths.** We provide mentorship, documentation, and support to help community members step into leadership roles.
- **Regular feedback.** We solicit feedback from underrepresented groups and use it to inform our practices.
### 2. Welcoming Culture
- **Code of Conduct.** We maintain a [Code of Conduct](CODE_OF_CONDUCT.md) that sets clear expectations and is actively enforced.
- **Inclusive language.** We use neutral, respectful language in documentation, discussions, and code.
- **No assumptions.** We don't assume gender, skill level, background, or motivation. We ask and listen.
- **Celebrate diversity.** We highlight contributions from people of all backgrounds and skill levels.
### 3. Accessible Documentation and Resources
- **Multiple formats.** Documentation is available in text, code examples, and (when feasible) video/visual formats.
- **Beginner-friendly guides.** We provide clear, step-by-step instructions for getting started, contributing code, reporting issues, etc.
- **Accessibility standards.** We follow WCAG 2.1 AA standards for web content and documentation.
- **Clear jargon explanation.** We define technical terms and explain concepts in multiple ways.
- **Multilingual support.** We welcome translations of documentation and aim to support non-English speakers.
### 4. Lowering Barriers to Entry
- **Async-first communication.** Not everyone can attend meetings in real time. We document decisions and support asynchronous participation.
- **Timezone-aware scheduling.** When we do hold synchronous events, we rotate times or provide recordings.
- **Beginner-friendly issues.** We label issues suitable for new contributors (`good-first-issue`, `help-wanted`) with clear guidance.
- **Mentorship pairings.** We connect newcomers with experienced contributors who can guide them.
- **Financial support.** Where feasible, we support attendance at conferences and events for contributors from underrepresented groups.
### 5. Safety and Respect
- **Code of Conduct enforcement.** We enforce our Code of Conduct fairly and consistently.
- **Multiple reporting channels.** People can report concerns anonymously or directly to maintainers.
- **Swift response.** We investigate reports promptly and take appropriate action.
- **No retaliation.** We protect people who report concerns in good faith.
- **Continuous improvement.** We regularly review our enforcement practices and adjust as needed.
### 6. Meaningful Participation Across Skill Levels
FeDIY recognizes that DIY communities span all skill levels—from complete beginners to experts. We support this diversity:
- **Beginner-welcoming.** Questions about basic concepts are always welcome. We celebrate learning.
- **Diverse contribution types.** We value bug reports, documentation improvements, design feedback, and testing—not just code.
- **Recognition.** We recognize contributions of all types, not just pull requests.
- **Collaborative problem-solving.** We work together on issues rather than placing all burden on issue reporters.
### 7. Addressing Domain-Specific Inclusion
FeDIY's federated project model serves many communities (crafting, making, cooking, etc.), each with unique demographics and barriers:
- **Cross-domain awareness.** We listen to leaders from different DIY domains about inclusion barriers specific to their communities.
- **Extensible design.** Our composable project model allows instances and extensions to tailor inclusion practices to their communities.
- **Content policy thoughtfulness.** We develop content policies in consultation with affected communities, not in isolation.
### 8. Accessibility for People with Sensory and Motor Differences
We are committed to building FeDIY to be fully accessible to people who are blind, low-vision, Deaf, hard-of-hearing, or have motor differences. This is not an afterthought—accessibility is a core design principle from day one.
#### Visual Accessibility
- **Alt text for all images.** Every image in a project (step photos, diagrams, material pictures) has descriptive alt text. We provide tools and guidance to help creators write good alt text.
- **Text-to-speech support.** The API provides structured data (project title, step descriptions, material lists) in formats suitable for text-to-speech clients. The bundled UI includes TTS functionality for reading instructions aloud.
- **Color contrast.** We maintain WCAG 2.1 AA contrast ratios throughout the UI. Project creators receive guidance on color contrast for their materials and visuals.
- **Scalable fonts and layouts.** Text can be resized to 200% without loss of functionality. Layouts reflow gracefully.
- **Screen reader compatibility.** The bundled UI uses semantic HTML, ARIA labels where needed, and is tested with popular screen readers.
#### Hearing Accessibility
- **Captions and transcripts.** Any audio or video content in instructions includes captions and full transcripts.
- **Visual indicators.** Audio cues or warnings are also provided as visual indicators (icons, text, animations).
- **Sound-independent design.** No information is conveyed through sound alone.
#### Motor Accessibility
- **Full keyboard navigation.** All functionality is accessible via keyboard. No mouse-only interactions.
- **Keyboard shortcuts.** Power users can navigate efficiently via keyboard.
- **No time-dependent interactions.** Users have sufficient time to read and interact with content. No auto-advancing carousels or expiring sessions that aren't adjustable.
- **Large click targets.** Buttons and interactive elements are large enough to easily activate with motor impairments.
- **Accessible form design.** Forms clearly label all inputs, provide clear error messages, and are easy to navigate with assistive devices.
#### Cognitive and Learning Accessibility
- **Clear language.** Instructions use plain, simple language and avoid jargon where possible.
- **Consistent navigation.** The UI is predictable and consistent across pages.
- **Multiple content formats.** Instructions are available as text, images, and (where possible) video or audio.
- **Adjustable reading level.** Where feasible, instructions can be displayed in simplified language.
- **Craft-specific considerations.** Different DIY domains may have unique accessibility needs (e.g., tactile learners for fiber arts, kinesthetic learners for woodworking). We work with community leaders to identify and address these.
#### Reading Comfort and Dyslexia Support
We recognize that reading text on screens is not equally comfortable for everyone. Dyslexia, visual stress, ADHD, and other reading differences are common, and we design our interface to accommodate them:
- **User-controlled fonts.** Users may choose their preferred typeface, including dyslexia-friendly options such as [OpenDyslexic](https://opendyslexic.org/) and [Atkinson Hyperlegible](https://brailleinstitute.org/freefont). The bundled UI ships with at least one dyslexia-friendly font available by default.
- **No font lock-in.** The bundled UI must not prevent browser or OS font overrides. Users who have configured their own reading fonts system-wide will have those respected.
- **Adjustable typography.** Users can control font size, line height, letter spacing, and word spacing. Generous spacing aids many readers, especially for step-by-step instruction text.
- **Adjustable line length.** Long line lengths are tiring and disorienting for many readers. The UI provides comfortable default line lengths and allows users to adjust them.
- **Low-visual-stress themes.** High-contrast black-on-white can cause visual stress for some readers. The UI offers off-white or tinted background themes as an alternative. Users may also apply custom color themes.
- **Settings are persistent.** Reading preferences are saved to the user's account and apply across all devices. Unauthenticated users can set display preferences via browser storage.
- **API-exposed preferences.** Display preferences are stored in the API so third-party clients can retrieve and honor them without requiring duplication.
#### Localization and Language Inclusion
We design FeDIY to be usable and readable across languages and locales:
- **All UI strings are externalized.** No display text is hardcoded in the application. This makes community translation straightforward without touching application code.
- **Community-driven translation.** Translation files live in the repository. Anyone can contribute a new locale or improve an existing one.
- **Content language tagging.** Projects carry a language tag (BCP 47). Search and display respect declared content language.
- **RTL script support.** Layout supports right-to-left scripts (Arabic, Hebrew, Persian, etc.) from the first UI design pass.
- **Locale-sensitive formatting.** Dates, times, numbers, and units of measure are formatted according to the user's locale, not hardcoded to any single convention.
- **No English-only default behavior.** The platform's default experience does not assume English-speaking users. Language preference is surfaced as a first-class setting.
#### How We Maintain Accessibility
- **From the start.** Accessibility is part of the design process, not an afterthought.
- **Testing.** We test with real assistive technologies (screen readers, speech recognition, switch control) and with people who use them.
- **Standards.** We follow WCAG 2.1 AA as a minimum. We aim for AAA where practical.
- **Feedback.** Users with disabilities can report accessibility issues; we prioritize fixing them.
- **Documentation.** We document accessibility features so users know what's available.
- **Creator support.** We help project creators make their content accessible (alt text tools, captions, etc.).
## Measuring Our Progress
We track the following metrics to assess our inclusion efforts:
| Metric | Current | Goal | Notes |
|--------|---------|------|-------|
| % of first-time contributors receiving response within 48 hours | TBD | 100% | Ensures newcomers feel welcomed |
| % of issues with beginner-friendly labels | TBD | 30%+ | Lowers barriers for new contributors |
| Diversity in maintainer team | TBD | Improve | Goal is to reflect community diversity |
| % of contributors from underrepresented groups | TBD | Improve | Tracked via anonymous surveys |
| Code of Conduct enforcement rate | N/A | 100% | All violations are addressed |
| Accessibility audit results | TBD | WCAG AA | Regular audits of docs and code |
| Accessibility issues resolved | TBD | 100% within 30 days | User-reported accessibility bugs are prioritized |
We will publish progress updates on these metrics quarterly.
## Feedback and Improvement
Inclusion is not a one-time effort—it's continuous. We welcome feedback:
- **Anonymous feedback form:** [link to be added]
- **Email:** <conduct@moturpin.com>
- **GitHub discussions:** Open an issue labeled `inclusion`
- **Community meetings:** Bring concerns to our (scheduled) community meetings
If you see something we're not doing well, please tell us. We're committed to listening and improving.
## Acknowledgments
This commitment is informed by:
- [Contributor Covenant Code of Conduct](https://www.contributor-covenant.org)
- [CHAOSS Community Health Analytics](https://chaoss.community/) and [DEI Project Badging](https://chaoss.community/diversity-and-inclusion-badging/)
- [The Good Docs Project](https://thegooddocsproject.dev/) — documentation for inclusive communities
- [Linux Foundation DEI Report](https://www.linuxfoundation.org/research/the-2021-linux-foundation-report-on-diversity-equity-and-inclusion-in-open-source)
- [Brittney Ball's "Creating an Inclusive Open Source Community"](https://medium.com/the-b-word/creating-an-inclusive-open-source-community-a-comprehensive-guide-a0590b941c9d)
- Communities in crafting, making, and DIY projects where we learn from existing inclusion efforts
---
**Last Updated:** May 2026
**Maintained by:** FeDIY Maintainers
**Next Review:** May 2027
+49 -35
View File
@@ -1,6 +1,7 @@
# Rust Nix Flake Template
# FeDIY
This template provides a reproducible Rust development environment using Nix flakes and the fenix toolchain.
FeDIY provides a reproducible Rust development environment using Nix flakes and the fenix toolchain.
Nix is optional for contributors: if you use it, `nix develop` gives you the exact tools this repository expects without needing to install them globally. If you do not use Nix, you can still work with the standard Rust toolchain.
## Quick Start
@@ -15,41 +16,31 @@ direnv allow
When you enter the devShell (via `direnv allow` or `nix develop`), the following happens automatically:
**Git Repository**: Initializes `.git` if not present
**Rust Targets**: Automatically adds common embedded Rust targets (ARM Cortex-M, RISC-V)
**Cargo Paths**: Sets up `$HOME/.cargo/bin` in PATH for cargo-installed binaries
**Welcome Banner**: Displays available tools and quick commands
No manual setup needed! Just start coding.
## Quickstart
## First Steps
```sh
nix flake init -t path:../flakes#rust
nix develop
cargo build
cargo test
```
## Embedded Rust Support
If you want a quick overview of what the shell provides, run:
The devShell automatically installs common embedded Rust targets via `rustup`:
| Target | Platform | Use Case |
|--------|----------|----------|
| `thumbv6m-none-eabi` | ARM Cortex-M0/M0+ | RP2040 (Pico) |
| `thumbv7em-none-eabihf` | ARM Cortex-M4F/M7F | STM32, nRF52840 |
| `riscv32imc-unknown-none-elf` | RISC-V 32-bit | ESP32-C3 (basic) |
| `riscv32imac-unknown-none-elf` | RISC-V 32-bit (atomic) | ESP32-C3 (advanced) |
**Note:** ESP32 Xtensa targets require espup or custom toolchains (see [esp-rs](https://github.com/esp-rs)).
```sh
nix run .#dev-helper
```
## Flatpak Packaging
This template supports building Flatpak packages for your Rust application.
This project supports building Flatpak packages for the FeDIY application.
### Build Flatpak Package
1. Ensure you have `flatpak-builder` installed.
2. Run:
1. Run:
```bash
make flatpak-build
@@ -66,8 +57,8 @@ Edit `flatpak/app.flatpak.json` to update app ID, runtime, build commands, or so
You can install and run the built Flatpak locally:
```bash
flatpak install --user build-flatpak/org.example.rustdevshell.flatpak
flatpak run org.example.rustdevshell
flatpak install --user build-flatpak/com.moturpin.fediy.flatpak
flatpak run com.moturpin.fediy
```
## Included Tools
@@ -80,14 +71,15 @@ flatpak run org.example.rustdevshell
| **rustfmt** | Rust code formatter |
| **rust-analyzer** | Language server for IDE integration |
| **rust-src** | Rust source code (for tools like rust-analyzer) |
| **probe-rs** | Embedded debugger/flasher for ARM targets |
| **espflash** | Flashing tool for ESP32 boards |
| **openocd** | JTAG/SWD debugger for ARM and other targets |
| **minicom** | Serial terminal for device output |
| **elf2uf2-rs** | Convert ELF to UF2 format (RP2040) |
| **picotool** | Pico-specific firmware operations |
| **avrdude** | AVR microcontroller programmer |
| **ravedude** | Rapid AVR development utility |
| **cargo-deny** | Audit dependencies for advisories and license policy |
| **cargo-edit** | Add/remove/upgrade Cargo dependencies from the CLI |
| **cargo-watch** | Auto-rebuild on file changes |
| **flatpak-builder** | Build Flatpak distribution packages |
| **psql / postgresql** | Local PostgreSQL development and inspection |
| **gettext** | Localization and translation workflow support |
| **chromium / playwright** | Browser-based UI and accessibility checks |
| **podman / podman-compose / buildah** | Linux-only OCI/container tooling |
| **pre-commit** | Run pre-commit hooks |
## Testing & Development Features
@@ -109,8 +101,11 @@ cargo clippy
# Format code
cargo fmt
# Build for embedded target
cargo build --target thumbv7em-none-eabihf --release
# Watch and rebuild on changes
cargo watch -x build
# Build a Flatpak
make flatpak-build
```
## Project Layout
@@ -118,8 +113,19 @@ cargo build --target thumbv7em-none-eabihf --release
```
Cargo.toml
Cargo.lock
docs/
adrs/ # Architecture decision records
contracts/ # API and behavior contracts (planning artifacts)
extensions/ # Extension model planning and examples
OPEN_QUESTIONS.md
ROADMAP.md
ARCHITECTURE.md
schemas/
project-core/ # Core project schema artifacts
extensions/ # Domain-specific extension schema artifacts
src/
└── main.rs (or lib.rs)
tests/
Makefile
.envrc
flake.nix
@@ -137,19 +143,27 @@ nix-shell
See project.toml for example metadata.
## Planning Documentation
- [Planning docs index](docs/README.md)
- [Roadmap](docs/ROADMAP.md)
- [Architecture baseline](docs/ARCHITECTURE.md)
- [Development workflow (TDD/BDD + GitHub Flow)](docs/WORKFLOW.md)
- [Open questions and clarification plan](docs/OPEN_QUESTIONS.md)
## Helper Tools
- **`nix run .#dev-helper`** - Display tool versions and availability
- **`nix run .#dev-helper`** - Display tool versions and availability, grouped by task
- **`cargo build`** - Build the project
- **`cargo check`** - Quick syntax check without building
- **`cargo doc --open`** - Generate and view documentation
## Packaging for nixpkgs
This template is structured for easy packaging in nixpkgs:
This project is structured for packaging in nixpkgs:
- All sources in `src/`
- `flake.nix` provides a devShell and template
- `flake.nix` provides a devShell and package outputs
- Add a `default.nix` or package expression as needed for nixpkgs
See [nixpkgs Rust packaging docs](https://nixos.org/manual/nixpkgs/stable/#rust) for more details.
+201
View File
@@ -0,0 +1,201 @@
# Code Review Guidelines
Code review is a fundamental part of FeDIY's development process. It's an opportunity to share knowledge, catch issues early, and build a stronger codebase together. This guide outlines how we conduct reviews in a respectful, inclusive, and constructive way.
## Core Principles
### 1. **Assume Good Intent**
Contributors come to FeDIY to build something good. Assume they're doing their best and want their code to be correct.
### 2. **Focus on the Code, Not the Person**
Review code and ideas, not the developer. Avoid comments like "This is stupid" or "You should know better." Instead: "This approach could lead to X issue. Could we try Y instead?"
### 3. **Respect Diverse Perspectives**
Different developers have different experiences, backgrounds, and approaches. Sometimes there's more than one right way to solve a problem.
### 4. **Be Constructive**
Your job as a reviewer isn't to reject ideas but to help the contributor improve their work. Ask questions, suggest alternatives, and explain your reasoning.
### 5. **Respond Promptly**
Aim to provide initial feedback within 48 hours. This keeps momentum and shows contributors we value their work.
### 6. **Be Kind**
Code review happens asynchronously and in writing. Words can be misinterpreted. Err on the side of kindness and clarity.
## What to Review
### Correctness
- Does the code do what it claims to do?
- Are edge cases handled?
- Could this code fail in unexpected ways?
- Are there potential security, performance, or accessibility issues?
### Design and Architecture
- Does this change align with our [ARCHITECTURE.md](ARCHITECTURE.md)?
- Does it follow our design patterns?
- Could this be implemented more simply?
- Will this change make the codebase harder to understand or maintain?
### Tests
- Are there tests? Do they cover the happy path and edge cases?
- Do tests actually test the claimed behavior?
- Would a reviewer understand what the code should do from the tests?
### Documentation
- Is the code documented? Is the documentation clear?
- Are public APIs documented?
- Are complex algorithms explained?
- Is there a comment explaining *why* a particular approach was taken?
### Code Quality
- Does it follow our style guide?
- Is it formatted correctly (`cargo fmt`)?
- Does it pass `cargo clippy`?
- Are variable and function names clear?
## How to Review
### Do
**Ask questions:** "What does this function return when X happens?"
**Explain your reasoning:** "I'm concerned about this approach because it could lead to Y. Have you considered Z?"
**Suggest alternatives:** "Another way to solve this might be..."
**Praise good work:** "Great catch on this edge case!" or "I like how you handled this—it's elegant."
**Admit uncertainty:** "I'm not sure about this part. Can you help me understand?"
**Provide context:** "This pattern conflicts with how we do it in module X. Let's align them."
**Acknowledge limitations:** "This might be a trade-off between X and Y. Let's discuss."
### Don't
**Nitpick style:** Linters and formatters handle this. Focus on substance.
**Demand perfection:** Good is good enough. Encourage incremental improvement.
**Approve blindly:** Actually review the code.
**Leave vague feedback:** "This doesn't seem right" isn't helpful. Be specific.
**Require your preferred style:** There's often more than one right way.
**Comment on things outside the PR's scope:** Stay focused.
**Use harsh language:** Code review isn't a place for snark or condescension.
## Example Reviews
### ❌ Not Great
```
This is wrong. Fix it.
```
(Not helpful, unclear, and discouraging.)
### ✅ Better
```
I'm concerned about this approach. The function reads `self.state` but doesn't
check if it's been initialized. In our current code, this could panic.
Have you considered checking `is_initialized()` first, or would it make sense
to initialize in the constructor?
I'm happy to help think through this if you'd like!
```
(Specific, explains the problem, suggests solutions, and is encouraging.)
## Review Checklist
Before approving a PR, confirm:
- [ ] Code is correct and handles edge cases
- [ ] Changes align with project architecture
- [ ] Tests are adequate and pass
- [ ] Documentation is clear
- [ ] Code follows style guidelines (`cargo fmt` and `cargo clippy` pass)
- [ ] Commit messages are clear
- [ ] No security, performance, or accessibility red flags
- [ ] Feedback has been respectful and constructive
## Handling Disagreement
Sometimes reviewers and contributors disagree. This is normal and healthy. When this happens:
1. **State your position clearly.** Explain why you think something should be different.
2. **Ask for their perspective.** They might have information you don't.
3. **Seek common ground.** Often there's a compromise that works.
4. **Escalate if needed.** If you can't agree, involve a maintainer.
5. **Respect the decision.** Once a maintainer decides, everyone moves forward.
Remember: disagreement about code is not personal. We're all trying to build something good.
## Feedback on Feedback
Code reviewers are also learning. If you feel feedback was disrespectful or unhelpful:
1. **Assume good intent.** The reviewer probably wasn't trying to be harsh.
2. **Ask for clarification.** "I'm not sure what you mean. Could you elaborate?"
3. **Suggest improvement.** "It would help me to understand the concern better if you explained..."
4. **Report if needed.** If the reviewer violates our Code of Conduct, report it.
## Special Cases
### First-Time Contributors
Spend a bit more time with PRs from first-time contributors. They're learning the project and may not know all our conventions yet. A bit of extra patience now builds a better long-term contributor.
### Large Changes
Big PRs are harder to review. If you're submitting a large change:
- Open an issue or discussion first to get buy-in on the approach
- Consider breaking it into smaller PRs
- Explain the overall goal clearly
As a reviewer of large changes, don't hesitate to ask for clarification or suggest breaking it up.
### Sensitive Topics
Some PRs touch on moderation, content policy, security, or inclusion. These need thoughtful, careful review:
- Take time to understand the context
- Consider asking multiple reviewers for input
- Be respectful of different perspectives
- Remember the human impact of these decisions
## Resources for Better Reviewing
- [Google Code Review Guidelines](https://google.github.io/eng-practices/review/)
- [Thoughtbot Code Review Etiquette](https://thoughtbot.com/blog/code-review-etiquette)
- [Rust API Guidelines](https://rust-lang.github.io/api-guidelines/)
- [OWASP Secure Coding Practices](https://owasp.org/www-project-secure-coding-practices-quick-reference-guide/)
## Questions?
- Unsure about a review? Ask for help in a comment.
- Feedback on the review process? Open an issue tagged `review-process`.
- Code of Conduct concerns? See [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md).
---
Thank you for contributing your time and expertise through code review. It makes FeDIY better!
**Last Updated:** May 2026
+93
View File
@@ -0,0 +1,93 @@
# Security Policy
## Reporting Security Vulnerabilities
FeDIY takes security seriously. If you discover a security vulnerability in the project, we appreciate your help in disclosing it responsibly.
**Please do not open a public GitHub issue for security vulnerabilities.**
Instead, please report security issues by emailing [security@moturpin.com] with:
- A clear description of the vulnerability
- Steps to reproduce the issue (if possible)
- Potential impact on users and systems
- Any proposed fixes you may have
You can also use GitHub's private vulnerability reporting feature by navigating to the Security tab of the repository and clicking "Report a vulnerability."
## What We Commit To
- **Acknowledge receipt** of your report within 48 hours
- **Provide an initial assessment** of the vulnerability within 5 business days
- **Keep you informed** of progress toward a fix
- **Publish security advisories** for confirmed vulnerabilities, with credit to the reporter (unless you prefer to remain anonymous)
- **Work toward a coordinated disclosure** timeline with you
## Security Expectations
While we work to maintain FeDIY's security, please understand:
- FeDIY is an open source project maintained by volunteers. Response times may vary.
- We follow responsible disclosure practices and expect the same from reporters.
- We ask that you allow us a reasonable time (typically 30-90 days) to release a patch before public disclosure.
- If you'd like to discuss timeline adjustments, please let us know.
## Security Best Practices for Users
### Running FeDIY
- **Keep dependencies updated.** Rust dependencies are managed via Cargo. Regularly run `cargo update` to get security patches.
- **Use HTTPS.** When deploying FeDIY, use HTTPS for all connections to prevent eavesdropping.
- **Secure your database.** PostgreSQL (or SQLite) instances should be properly secured with strong authentication and restricted network access.
- **Audit access.** Regularly review who has administrative access to your FeDIY instance.
- **Monitor logs.** Watch logs for suspicious activity and configure alerting for authentication failures.
### ActivityPub Federation
- FeDIY federates via ActivityPub. Be aware that activities may be shared with other federated instances.
- Instances should enforce their own content policies and block malicious instances if needed.
- User data shared via federation should be treated as public and potentially persistent.
## Development Security
Contributors should:
- **Review code carefully.** Security vulnerabilities can hide in unexpected places. Code review is our first defense.
- **Use secure coding practices.** Avoid SQL injection, XSS, CSRF, and other common vulnerabilities. See [OWASP Top 10](https://owasp.org/www-project-top-ten/) for reference.
- **Validate all input.** Never trust user input. Always validate and sanitize data before processing.
- **Use type safety.** Rust's type system prevents many classes of vulnerabilities. Use it effectively.
- **Document security decisions.** If you make security-related changes, document the reasoning in commit messages or ADRs.
## Supported Versions
| Version | Status | Security Updates |
|---------|--------|------------------|
| 0.1.x | Alpha | Best effort |
| Future | TBD | Will be defined |
**Note:** During the early alpha phase (v0.1), security patches may be released ad-hoc. As the project matures, we will establish a formal versioning and patching policy.
## Vulnerability Disclosure
When we discover or are notified of a security vulnerability, we will:
1. Confirm the vulnerability and assess its severity
2. Develop and test a fix
3. Coordinate a release with security patches
4. Publish a security advisory with details and credit
5. Acknowledge and thank the reporter
## Security Contacts
- **Email:** security@moturpin.com
- **GitHub Security Advisory:** Use the "Report a vulnerability" tab in the GitHub repository
## Additional Resources
- [OWASP Application Security](https://owasp.org/)
- [Rust Security Guidelines](https://anssi-fr.github.io/rust-guide/)
- [CISA Secure Software Development Framework](https://csrc.nist.gov/projects/secure-software-development-framework/)
---
**Last Updated:** May 2026
+8 -8
View File
@@ -1,28 +1,28 @@
{ pkgs }:
let
lib = pkgs.lib;
templateName = builtins.baseNameOf (toString ./.);
projectName = builtins.baseNameOf (toString ./.);
in
{
${templateName} = pkgs.stdenvNoCC.mkDerivation {
pname = templateName;
${projectName} = pkgs.stdenvNoCC.mkDerivation {
pname = projectName;
version = "0.1.0";
src = ./.;
dontBuild = true;
installPhase = ''
mkdir -p $out/share/${templateName}
mkdir -p $out/share/${projectName}
if [ -d src ]; then
cp -r src $out/share/${templateName}/
cp -r src $out/share/${projectName}/
fi
for f in README.md project.toml flake.nix default.nix shell.nix Makefile .editorconfig .gitignore; do
if [ -f "$f" ]; then
cp "$f" $out/share/${templateName}/
cp "$f" $out/share/${projectName}/
fi
done
'';
meta = with lib; {
description = "Template project: ${templateName}";
license = licenses.unfreeRedistributable;
description = "FeDIY project source bundle: ${projectName}";
license = licenses.cc-by-sa-40;
platforms = platforms.all;
};
};
+473
View File
@@ -0,0 +1,473 @@
# FeDIY Architecture (Planning Baseline)
This document captures current architectural intent. It is a planning artifact and should be refined as implementation decisions mature.
## System Boundaries
Primary system responsibilities:
- Expose a stable HTTP API as the primary interface for all clients.
- Host and render DIY project content through a bundled web UI that consumes the public API.
- Manage local accounts and authorization.
- Federate selected objects and activities using ActivityPub.
- Enforce local moderation policy for both local and remote content.
Out of scope for early phases:
- Rich social graph features beyond project-oriented interactions.
- Highly customized recommendation systems.
## Packaging and Deployment Targets
FeDIY is intended to be shipped and operated through a small set of first-class packaging targets so instance operators can choose the deployment style that fits their environment:
- **Nix flake/devShell**: reproducible development and build environment for contributors and operators who prefer Nix. It is a convenience path, not a requirement for contributing.
- **Flatpak**: desktop-friendly distribution path for bundled client or companion tooling where applicable.
- **OCI/Docker container image**: a standard containerized deployment path for managed hosting, Kubernetes, and simple `docker compose` installs.
- **NixOS module**: optional system integration for operators already using NixOS.
These targets should share the same application artifact and configuration model where possible. Packaging differences should be limited to how the binary is delivered, configured, and run; they should not fork the core runtime behavior. Contributors should be able to work productively with standard Rust tooling even if they never enter the Nix shell.
The flake and related packaging shells should be reviewed periodically so the included tools stay aligned with current phase needs. The default posture is to keep the dev environment lean and add tools only when they directly support active work such as building, testing, localization, accessibility validation, container packaging, or release tasks.
## Core Domains
- Identity and actors.
- Project authoring and publishing.
- Federation transport and protocol translation.
- Moderation and trust policy.
- Search and discovery.
## Project Domain Baseline
Current product definition:
- A project is a defined work process.
- Core project structure includes materials/ingredients, required tools, and ordered step-by-step instructions.
- Steps may include embedded media hosted on this instance or linked from external sources.
- Projects may include external canonical links (for example homepage, repository, or source publication).
- Projects may include multiple typed canonical links (for example homepage, repository, build instructions, video walkthrough, or source publication). Canonical links are project-scoped by default and remain stable across revisions; version-scoped links are allowed when a specific published revision needs its own artifact or source reference.
- Explicit project versioning is preferred and will be part of the domain model.
- The project model is composable: a minimal core plus optional domain-specific extensions.
- Domain-specific detail (for example knitting patterns/yarns, 3D print profiles/STLs, electronics BoM data) should be representable without being mandatory for all instances.
- First-party FeDIY focuses on a stable extension mechanism rather than implementing every niche schema directly.
- Materials are project-scoped entries with a fixed core shape: display name, structured quantity, unit, and optional note. Material entries are embedded within a project revision rather than modeled as independent top-level entities in Phase 1. Each material entry can carry the same extension payload mechanism as project-level extensions for domain-specific attributes (yarn weight, fibre content, filament diameter/material, wood species/grade, electronics component value/package).
- Material extensions use the same typed JSON block model as project extensions: namespace, type identifier, version, and payload. Clients discover available material extensions from explicit material-entry metadata. Known blocks are schema-validated; unknown optional blocks are preserved and round-tripped; unknown required blocks can be rejected until the instance supports them.
- Required tools are project-scoped entries with a lightweight core shape: display name and optional note. Tools are embedded within a project revision rather than modeled as independent top-level entities in Phase 1. Each tool entry can carry optional metadata such as skill level, safety notes, and alternatives. A shared tool taxonomy is a future option, not a Phase 1 requirement.
- A federated material catalog is a long-term goal: community-defined material types and shared taxonomy entries could be federated as ActivityPub objects, allowing instances to reference a common vocabulary without requiring central authority.
- Project-level extensions are stored as typed JSON blocks on the revision, each with a namespace, type identifier, version, and payload. Namespaces should be collision-resistant (for example reverse-DNS or URL-based identifiers). Clients discover available extensions from explicit revision metadata. Known extension blocks are schema-validated; unknown optional blocks are preserved and round-tripped; unknown required blocks can be rejected until the instance supports them.
### Project Revision Lifecycle
FeDIY uses a hybrid draft + immutable revision model:
- **Drafts are mutable working copies.** Authors edit a draft until they publish it.
- **Publishing creates an immutable numbered revision.** A publish action snapshots the complete project state: materials, tools, steps, media references, canonical links, extension payloads, and any referenced sub-project pointers.
- **Revisions are append-only.** Once published, a revision never changes. Corrections or updates are made by creating a new draft from the latest published revision.
- **Revision numbering is monotonic per project.** Revision 1 is the first published snapshot; later publishes increment the number.
- **History is first-class.** The API and UI expose the full revision history by default, with the latest published revision presented as the canonical current view.
- **Draft visibility is restricted.** Drafts are visible only to the author and explicitly authorized collaborators; they are not part of public history until published.
- **Supersession is explicit.** A newly published revision supersedes the previous published revision, but the older revision remains addressable for audit, attribution, and history browsing.
- **Project references are recursive by graph, not by inline body embedding.** A project may reference another project as a sub-process or prerequisite (for example taco recipe -> taco meat recipe). The reference resolves to a specific published revision, so downstream recipes remain stable even if the referenced project is later updated.
- **Cycle detection is required.** The system must prevent or safely collapse cyclic project-reference graphs so recursive composition cannot create infinite expansion in the API or UI.
- **Extension payloads are versioned with the revision.** A revision snapshot includes extension data as it existed at publish time so clients can render or compare historical states accurately.
## Client and Front-End Strategy
The server exposes a stable, documented HTTP API as its primary interface. The bundled web UI is a first-party client of that same API — it receives no privileged server-side access that a third-party client could not also use.
Principles:
- **API-first**: every user-facing capability is reachable through the public API before the bundled UI uses it.
- **No server-side rendering shortcuts**: the bundled UI must not depend on server-internal state or bypass the API layer.
- **Third-party clients are first-class**: authentication, content negotiation, and capability negotiation must work the same way for any client origin.
- **Content negotiation**: the server responds to `Accept: application/activity+json` (or `application/ld+json`) for federation endpoints, and `Accept: application/json` for the API, allowing a single URL namespace to serve both.
- **CORS**: cross-origin API access is supported for read-only public resources, with authenticated endpoints requiring explicit opt-in by the instance operator.
- **Bundled UI is optional at deploy time**: an instance operator should be able to run the backend and serve their own front-end without modifying server code.
API surface areas:
- Public read API: browse projects, actors, and search without authentication.
- Authenticated user API: authoring, account management, preferences.
- Moderation API: moderation actions and audit review, scoped by role.
- Federation endpoints: ActivityPub inbox/outbox per the ActivityPub specification.
- Well-known endpoints: WebFinger, NodeInfo, and instance metadata.
Bundled web UI:
- Delivered as static assets served from the same origin.
- Communicates only through the public API.
- Treated as the reference client for API usability validation.
- Should degrade gracefully where JavaScript is unavailable where practical.
- Must support per-user display preferences: font choice (including dyslexia-friendly fonts), size, line spacing, and contrast settings persisted to the user's account.
- Must not hardcode fonts or layout in ways that prevent user override.
## Logical Components
- Public HTTP API layer (routing, auth middleware, content negotiation, CORS).
- Domain service layer for project and account workflows.
- Federation layer (inbox/outbox, signing, verification, retries).
- Persistence layer for local and federated records.
- Moderation policy engine and audit log.
- Bundled web UI (static asset delivery).
- Background workers for delivery, indexing, and maintenance tasks.
## Data and Object Strategy
- Separate local canonical records from imported federated records.
- Preserve source metadata for remote content and actor provenance.
- Track object lifecycle states to support idempotent federation processing.
- Persist project data as core fields plus extension payloads so instances can tailor domain detail without fragmenting the base model.
- Material entries within a project carry the same extension payload structure as the project itself; domain-specific material attributes are co-located with the material entry rather than encoded in project-level fields.
## Persistence Layer Architecture
### Database
PostgreSQL is the primary persistence target.
Reasons:
- **JSONB**: ActivityPub objects and extension payloads are stored as structured JSON with PostgreSQL's JSONB operators. Extension payloads can be queried, indexed, and validated without an external document store.
- **Native full-text search**: PostgreSQL's built-in FTS with `tsvector`/`tsquery` eliminates an external search service for Phase 1. Language-specific configurations (stemming, stop words) are available per-column.
- **Transactional consistency under federation load**: federation fan-in (many incoming AP activities from many peers) involves concurrent writes. PostgreSQL's MVCC concurrency model and row-level locking handle this safely. SQLite's single-writer model would be a bottleneck under the same load.
- **Broad managed hosting support**: PostgreSQL is available on every major cloud platform and hosting provider with zero operational effort, lowering the barrier for instance operators.
SQLite is **not in scope for Phase 1** but is explicitly not ruled out as a future lightweight self-hosting option (see Repository Abstraction below).
### Repository Abstraction
No business logic or domain service code queries the database directly. All persistence operations go through a repository interface layer:
- Each domain aggregate (project, account, actor, moderation record, etc.) has a corresponding repository interface defined as a trait.
- The domain service layer depends only on those traits, not on any database library types.
- The PostgreSQL implementation of each trait is the only first-party implementation.
- A SQLite implementation could be added in a future phase by implementing the same traits with SQLite-dialect queries — zero changes to domain logic or API handlers would be required.
- The repository layer is also the natural seam for test doubles: domain logic tests can use an in-memory implementation of the traits without a running database.
### Query Library
The query library choice is deferred to the implementation ADR, but the constraints are:
- Must support async execution.
- Must support both PostgreSQL and SQLite dialects (to keep the SQLite future option open).
- Compile-time query checking is strongly preferred to catch SQL errors before runtime.
- `sqlx` satisfies all three constraints and is the expected choice, but the decision is recorded in the ADR.
### Migration Strategy
See Q28. Database migrations are run as part of application startup (or a separate migrate subcommand) and are versioned, idempotent, and checked into source control alongside the schema they produce.
## Federation Strategy
- Start with a narrow, explicit ActivityPub profile.
- Prefer strict validation and clear rejection reasons over permissive parsing.
- Use replay-safe request validation and deterministic retry behavior.
- Maintain an interop test matrix for protocol behaviors.
## Content Integrity
Certain categories of content are prohibited on any FeDIY instance regardless of operator configuration. These are not moderation policy — they are non-negotiable constraints enforced at the software level. The guiding principle is **consent**: the prohibited categories share the property that no legitimate consent to the content's creation or publication can exist.
### Hardcoded Prohibitions
| Category | Rationale | Enforcement approach |
|---|---|---|
| Child Sexual Abuse Material (CSAM) | Minors cannot consent to sexual content; production is abuse | Perceptual hash-matching against NCMEC hash database on every upload |
| Non-Consensual Intimate Imagery (NCII) | Subject has not consented to distribution | Hash-matching against StopNCII or equivalent database on every upload |
| Doxxing | Individual has not consented to publication of their private identifying information | Upload-time pattern detection (phone, address, government ID formats) as a signal; mandatory human-review flagging pipeline; rapid takedown tooling |
### What Is Not Hardcoded
Weapons, violence, and dual-use content are **not** hardcoded prohibitions. Legitimate DIY projects — fireworks, blacksmithing, blade-smithing, pyrotechnics, casting — can be indistinguishable from prohibited content at the software level. This category is handled by operator content policy and community moderation tools, not by the platform software.
### Hash-Matching Infrastructure
- All media uploaded to a FeDIY instance is processed through the hash-matching pipeline **before** storage is confirmed. A match results in rejection of the upload and triggers the reporting workflow.
- Hash databases are not bundled with the software. Operators must configure the integration (NCMEC PhotoDNA, Microsoft CSAM hash API, or equivalent) before media upload is enabled. The application refuses to enable media upload without a configured hash-matching endpoint.
- Hash-matching is performed locally on the server; media content is never transmitted to a third-party hash service. Only the computed hash is compared.
- FeDIY provides clear integration documentation and a test mode for operators to verify their configuration before going live.
### Doxxing Detection
- Upload-time and submission-time scanning checks text content for patterns consistent with personal identifying information: phone number formats, postal address patterns, government ID number patterns (country-configurable), and combinations that together identify an individual.
- Pattern matching is a signal, not a block: false positives (a project step referencing a phone socket) must not prevent legitimate content. Matched content is flagged for moderator review, not auto-rejected.
- All instances must have at least one active moderator account to receive flagged content alerts before registrations are opened.
### Reporting and Legal Obligations
- When a CSAM match is confirmed by a moderator, the operator is required to report to the relevant national authority (NCMEC CyberTipline in the US, IWF in the UK, etc.). FeDIY provides a reporting workflow and documentation; the legal obligation rests with the instance operator as the data controller and platform host.
- NCII confirmed matches follow the StopNCII/similar removal workflow; the operator notifies the subject where possible.
- The platform stores a minimal, anonymised record of confirmed violations and reports for the operator's legal compliance purposes.
## Moderation and Safety Strategy
### Instance and Moderator-Level Controls
- Local policy is authoritative for what is visible on this instance.
- Policy controls exist at three levels: object, actor, and instance.
- Moderation actions produce auditable events.
- Appeals and reversal policy should be documented before broad federation rollout.
### User-Level Personal Moderation
Users have unilateral, moderator-independent tools to protect themselves from bad actors. These do not require moderator approval and take effect immediately for the acting user:
- **Block users**: block specific local or remote accounts. A blocked account cannot interact with the user's content and the user does not see the blocked account's content.
- **Block instances**: block an entire remote instance. The user sees no content from that instance and cannot be interacted with by its users.
- **Mute users**: suppress a user's content from the user's feed without full blocking.
- **Keyword and wildcard filtering**: filter content containing specific words, phrases, or wildcard patterns from the user's feed and notifications. Filters operate client-side or server-side at the user's preference.
- **No moderator gate**: user-level blocks, mutes, and filters are the user's own data. Instance moderators cannot prevent a user from protecting themselves.
### Shareable Social Moderation
Users may choose to share their personal moderation and curation data with others:
- **Exportable/importable block lists**: users can export their block list as a portable format (JSON-LD or similar) and share it. Others can import it in whole or selectively.
- **Subscribable block lists**: a user may publish a block list as a live resource. Subscribers can opt in to apply it automatically or review updates manually.
- **Recommendation lists**: users can publish curated lists of projects, accounts, or tags they recommend. Lists are first-class objects with their own AP identity.
- **Personal collections and bookmarks**: users can organize saved projects into named collections and optionally make those collections public or shareable.
- **Community-defined lists**: groups of users (communities, instances) can collaboratively maintain shared lists for moderation or discovery purposes.
- **Attribution and transparency**: shared lists carry attribution to the list maintainer. Subscribers know whose judgment they are trusting.
## Localization and Internationalization Strategy
FeDIY is designed to be usable across languages and locales from the beginning:
- **Locale-aware API**: all user-facing strings are externalized and never hardcoded in the API layer. The API surfaces language/locale metadata about content (project language, author locale) to allow clients to filter, translate, or display appropriately.
- **Content language tagging**: projects carry a declared language tag (BCP 47). Instances may restrict accepted content languages or accept all. Federated objects include language metadata.
- **UI string externalization**: all bundled UI strings are stored in locale files (e.g., JSON or gettext PO format) from the start. The architecture does not permit hardcoded display strings.
- **RTL layout support**: layout must support right-to-left scripts (Arabic, Hebrew, Persian, etc.) from the first UI design pass. CSS logical properties are preferred over physical ones.
- **Locale-sensitive formatting**: dates, times, numbers, and units use locale-aware formatting rather than hardcoded conventions.
- **Community translation**: translation files are exposed in the repository so that the community can contribute translations without touching application code.
- **Locale as a user preference**: authenticated users can set their preferred locale, stored in their account. Unauthenticated users can set locale via browser `Accept-Language` or an explicit UI control.
- **Search and indexing**: full-text search configurations are locale-aware where the persistence layer supports it (e.g., PostgreSQL language dictionaries).
## Non-Functional Requirements
- **Accessibility**: designed from the start to be inclusive for people with sensory and motor differences. Includes WCAG 2.1 AA minimum, text-to-speech hooks, alt text for all visual content, captions for audio, keyboard navigation, and support for assistive technologies.
- **Localization**: all UI strings externalized and locale-ready from day one; RTL layout support; content language tagging; community-translatable.
- **Reading comfort**: users can override fonts (including dyslexia-friendly typefaces), size, line spacing, and contrast. No system-level or application-level font lock-in.
- **Reliability**: resilient delivery and retry strategy for federated traffic.
- **Security**: signature verification, key management, least-privilege defaults, and safe CORS policy.
- **Performance**: predictable latency for local reads and bounded queues for remote events.
- **Operability**: metrics, logs, and runbooks for incident response.
- **API stability**: public API changes follow a deprecation policy; breaking changes require a version increment.
## Privacy and Legal Compliance Strategy
FeDIY is designed with privacy as a first-class concern. The architecture must satisfy GDPR (and equivalent data-protection regulations) by design, not by retrofit.
### Data Minimisation and Purpose Limitation
- Collect only the personal data required for the platform to function.
- Every personal data field must have a documented purpose. Fields without a clear purpose are not collected.
- Access to personal data is scoped to the minimum needed for each system component.
### Lawful Basis for Processing
### Personal Data Register
All personal data collected by FeDIY instances is documented here. Every field has a stated purpose and lawful basis. No field is collected without both.
#### Required account fields (processed under contract)
| Field | What is stored | Purpose | Retention |
|---|---|---|---|
| Email address | Plaintext (normalised) | Account recovery, notifications, operator contact | Duration of account; deleted on erasure |
| Password | Argon2id hash only — plaintext never stored or logged | Authentication | Duration of account; deleted on erasure |
| Handle (`@user@instance`) | Plaintext; URL-safe string | AP actor identity, addressability, federation | Duration of account; old handles redirect to new after a change; deleted on erasure |
| Display name | Plaintext; user-chosen, pseudonym allowed | Human-readable identity in UI and AP objects | Duration of account; deleted on erasure |
| Minimum age verified | Boolean (`true`/`false`) — raw date of birth is **not stored** | Compliance with COPPA/GDPR Art. 8 age gate; raw DOB is used once at registration to derive this flag and then discarded | Duration of account; deleted on erasure |
| Account creation timestamp | UTC timestamp | Audit, legal compliance | Duration of account; may be retained in anonymised moderation records after deletion |
#### Optional profile fields (processed under contract — user chose to provide them)
| Field | Purpose | Retention |
|---|---|---|
| Bio / about text | Public self-description | Duration of account; deleted on erasure |
| Avatar image | Visual identity in UI and AP actor object | Duration of account; deleted on erasure |
| Header / banner image | Profile page decoration | Duration of account; deleted on erasure |
| Location (free text, not geocoded) | Community context; user-declared, not verified | Duration of account; deleted on erasure |
| Preferred crafts / interests | Discovery and personalisation | Duration of account; deleted on erasure |
| Pronouns | Respectful interaction | Duration of account; deleted on erasure |
| External links (website, social profiles) | Attribution and cross-platform identity | Duration of account; deleted on erasure |
| Preferred locale | UI language and formatting | Duration of account; deleted on erasure |
| Display preferences (font, size, spacing, contrast) | Reading comfort and accessibility | Duration of account; deleted on erasure |
#### Session and authentication data (processed under contract)
| Field | What is stored | Purpose | Retention |
|---|---|---|---|
| Session token | Opaque cryptographic token (server-side record) | Authenticated API access | Purged on logout; purged on expiry; all tokens purged on account deletion |
| Token expiry | Timestamp | Session lifecycle management | Purged with token |
| Security event log | Timestamp + account ID + event type (login, logout, failed login, password change) — **no IP address** | Audit trail for account security events | Short retention (30 days); purged on account deletion |
#### IP addresses
**IP addresses are never written to persistent storage.** They are present in the request context during processing and discarded when the request completes. Brute-force and abuse detection uses in-memory rate limiting scoped to the running process, not a persistent IP log.
This is a deliberate data minimisation decision. The privacy notice must state it explicitly as a feature of the platform's approach.
#### Content data (processed under contract)
| Data | Notes | Retention |
|---|---|---|
| Published projects (all fields, media, steps) | Publicly visible; federated to AP peers | Tombstoned on deletion (not fully erased if referenced by others); see Right to Erasure section |
| Draft projects | Private; never federated; not visible to other users | Fully deleted immediately on account deletion or on user request |
| Media attachments | Images, files uploaded to the instance | Deleted with the content they belong to |
| Tags, materials, tools associated with projects | Part of the project record | Same lifecycle as the project |
#### Interaction data (processed under contract)
| Data | Notes | Retention |
|---|---|---|
| Follows (outgoing and incoming) | Social graph; federated as AP Follow/Accept activities | Deleted on account deletion; unfollow activity sent to peers |
| Likes / favourites | Interaction record | Deleted on account deletion |
| Bookmarks and personal collections | Private by default | Deleted on account deletion; included in data export |
| Block list | Personal moderation data | Deleted on account deletion; included in data export |
| Mute list | Personal moderation data | Deleted on account deletion; included in data export |
| Keyword filters | Personal moderation data | Deleted on account deletion; included in data export |
#### Moderation and safety records (lawful basis: legal obligation / legitimate interest)
| Data | Notes | Retention |
|---|---|---|
| Reports filed by a user | User's own report history | Included in data export; deleted on account deletion (report content retained in anonymised form) |
| Moderation actions taken against a user | Actions, outcomes, dates | Anonymised at account deletion time (personal identifiers removed, safety record retained for legal compliance) |
| CSAM / NCII violation records | Anonymised record of confirmed violations and reports filed | Retained for operator's legal compliance obligations regardless of account status |
#### Federated / remote actor data (lawful basis: legitimate interest — necessary to operate the federation)
| Data | Notes | Retention |
|---|---|---|
| Remote actor profile cache | Handle, display name, AP actor URL, public key | Retained while needed for federation processing; purged when a `Delete` activity is received for the actor |
| Received AP activities | Cached copies of federated content from remote users | Retained while operationally needed; purged on receipt of `Delete` |
#### Analytics (lawful basis: legitimate interest — only if truly anonymised)
- First-party analytics are in scope, but must be **truly aggregate and anonymised** — not pseudonymised per-user event streams.
- Aggregate statistics (daily active users, most-viewed projects, search term frequency) that cannot be linked to any individual are not personal data under GDPR and require no consent.
- If per-user behavioural events are ever collected — even temporarily before aggregation — they become personal data at the point of collection and require explicit consent.
- The default configuration ships with analytics **off**. Operators enable it and are responsible for ensuring their approach stays within the anonymised boundary or obtains the required consent.
### Lawful Basis Summary
- **Contract**: required account fields, optional profile fields, session data, content data, interaction data.
- **Legal obligation**: age verification, CSAM/NCII reporting records, moderation records for legal compliance.
- **Legitimate interest**: federated actor cache, security event log, truly anonymised analytics.
- **Consent**: per-user behavioural analytics if ever collected; any future non-essential processing not covered above.
- Processing logs record the lawful basis used for each data category.
### Right to Access (Article 15)
- Users can request a full export of all personal data held about them via a self-service API endpoint.
- The export is machine-readable (JSON), human-readable, and covers: account data, published and draft content, interactions (follows, likes, bookmarks), moderation history affecting the user, and session/audit records.
- Federated data about the user held by remote instances is outside the local instance's control; exports note this explicitly.
### Right to Erasure / Right to be Forgotten — Technical Design
GDPR Article 17 (and equivalent laws in other jurisdictions) defines erasure at two levels. FeDIY must handle both:
**Level 1 — Local erasure (the account deletion step):**
- Users initiate deletion via a self-service workflow with no moderator or admin involvement required.
- Local erasure covers: account credentials, profile fields, email address, private/draft content, session tokens, IP logs beyond the retention window, interactions data (follows, likes, bookmarks, block lists) that is not itself public.
- Draft projects (never published) are deleted immediately.
- Deleted account data is fully purged within a defined maximum window (e.g. 30 days), not merely soft-deleted. The purge window is disclosed in the privacy notice.
- A deletion-in-progress state is visible to the user while processing completes.
**Level 2 — Propagation to third-party controllers (GDPR Art. 17(2)):**
- GDPR Article 17(2) requires that where a controller has made personal data public, it must take *reasonable steps* to inform other controllers processing that data of the erasure request. For FeDIY, this means federated instances.
- FeDIY fulfils this via ActivityPub `Delete` activities sent to all known federation peers that have received activities from this actor.
- `Delete` is sent for: the actor object itself, all known published objects (projects, activities).
- Delivery is best-effort with retry. FeDIY cannot *compel* remote instances to comply — this is a known limitation of the federated model, and the privacy notice must state it clearly.
- A log of which peers received the `Delete` activity (and delivery status) is retained for the operator's accountability records. This log is separate from the user's personal data and may be kept for legal compliance.
**Tombstoning vs. full erasure of public content:**
- Publicly published content that is referenced by other objects (e.g. a project that has been boosted or commented on by other users) may be replaced by an ActivityPub `Tombstone` rather than silently deleted. The `Tombstone` preserves object identity without reproducing the content or the author's personal data.
- The privacy notice and the deletion UI must clearly explain: (a) the distinction between draft/private data (deleted) and published content (tombstoned), and (b) the federation propagation limitation.
- A user who wants all traces removed must be told honestly what FeDIY can and cannot control.
**Permitted retentions (GDPR Art. 17(3) exceptions):**
- Moderation and safety records may be retained in anonymised form where necessary for legal compliance (e.g. CSAM reporting obligations, abuse records). These are anonymised at deletion time: the personal identifiers are removed but the safety record is kept.
- Legal hold: if an account is under active investigation or legal proceedings, deletion may be suspended for the duration. The user must be informed of the hold.
- Financial transaction records (where applicable) must comply with applicable tax and accounting retention laws, which may be longer than the general data window.
**RTBF for individual content items (not full account deletion):**
- A user may request deletion of specific published content (a project, a comment) without deleting their entire account.
- The same tombstone/propagation logic applies per object.
- This supports the GDPR right to withdraw consent for a specific published item without requiring full account closure.
### Multi-Jurisdiction Compliance Matrix
FeDIY is an open, self-hostable, federated platform. Instance operators may be subject to different legal regimes depending on where they operate and where their users are located. The architecture must support compliance across the primary regulatory regimes; instance operators are responsible for customising behaviour to their jurisdiction.
| Jurisdiction | Law | Erasure/RTBF right | Deletion SLA | Notes |
|---|---|---|---|---|
| EU / EEA | GDPR Art. 17 | Yes — right to erasure + propagation | Without undue delay; typically ≤30 days | Includes Art. 17(2) propagation obligation |
| UK | UK GDPR (post-Brexit) | Yes — equivalent to EU GDPR | Same as EU GDPR | Applies to UK users/controllers |
| California, US | CCPA/CPRA | Yes — right to delete | 45 days (extendable to 90) | Opt-out of sale/sharing; right to correct |
| Virginia, US | VCDPA | Yes — right to delete | 45 days | Opt-out of targeted advertising |
| Colorado, US | CPA | Yes | 45 days | Global Privacy Control must be honored |
| Connecticut, US | CTDPA | Yes | 45 days | |
| Texas, US | TDPSA | Yes | 45 days | Applies broadly to controllers |
| Other US states | Various (and growing) | Varies | Typically 4590 days | Architecture must be jurisdiction-agnostic |
| Brazil | LGPD Art. 18 | Yes — right to deletion | Reasonable time | Applies to data of Brazilian residents |
| Canada | PIPEDA / C-27 | Limited currently; C-27 will add explicit right | Bill C-27 pending | Design for upcoming CPPA |
| UK / Australia | Privacy Act 1988 (AU) | Limited; reform ongoing | Varies | Design to accommodate |
**Architectural implications:**
- **Jurisdiction-agnostic deletion workflow**: the erasure workflow is the same regardless of the user's jurisdiction; the operator configures any jurisdiction-specific behaviour (SLA, exceptions, notices) via instance settings.
- **Configurable SLA timers**: instance operators can set the deletion SLA window (e.g. 30 days for GDPR, 45 days for CCPA) via configuration. The default should satisfy the strictest common requirement.
- **Opt-out signals**: the architecture must support Global Privacy Control (GPC) header signals, which California (and others) require businesses to honor. The API and UI must process GPC as an opt-out of data sale/sharing.
- **No data sale**: FeDIY does not sell user data; this simplifies compliance but opt-out infrastructure may still be needed for operators who use analytics or advertising services.
- **Right to correct**: both GDPR (Art. 16) and CCPA/CPRA provide this right. Self-service profile and content editing satisfies it.
- **Response time tracking**: the system must be capable of recording when a deletion request was received, what was deleted, and when the purge completed, to support operator accountability obligations under multiple laws.
### Right to Rectification (Article 16)
- Users can correct or update their account profile data at any time without requiring moderator involvement.
- Updates to personal data propagate to federated instances via ActivityPub `Update` activities.
### Right to Data Portability (Article 20)
- The data export (see Right to Access) is in a portable, interoperable format.
- Where possible, exported project data can be imported into another FeDIY instance or compatible platform.
### Data Retention Limits
- A configurable retention policy governs how long the following categories are kept:
- Authentication logs and failed login records: short retention (e.g. 3090 days) unless a security incident requires longer.
- Session tokens: purged on logout and on expiry.
- IP address logs: not stored beyond what is operationally required; never logged against content in a way that persists indefinitely.
- Deleted account data: fully purged within a defined window after the deletion request is processed (e.g. 30 days), except for legally required anonymised moderation records.
- Instance operators must be able to configure retention windows to meet their local legal obligations.
### Federated Data and Third-Party Instances
- When a user deletes their account, a best-effort `Delete` activity is sent to known federated peers. FeDIY cannot compel remote instances to comply.
- The privacy notice must clearly explain that content shared via federation may persist on remote instances beyond FeDIY's control.
- FeDIY does not store personal data about remote users beyond what is strictly required to process incoming activities.
### Children's Privacy
- FeDIY does not knowingly collect personal data from children under the age of 13 (or the applicable age in the user's jurisdiction).
- Age verification approach (self-declaration, parental consent, or age-gate) must be defined before Phase 1 launch.
### Privacy Notice
- A machine-readable and human-readable privacy notice must be published at a well-known URL before any public instance accepts registrations.
- The notice describes: what data is collected, why, how long it is retained, how to exercise rights, and contact information for the data controller.
- Instance operators are data controllers for their own instances. FeDIY provides a template notice but operators are responsible for customising it to their jurisdiction.
## Architecture Decision Practice
- Decisions are captured as ADRs in [docs/adrs/](adrs/).
- Each ADR includes: context, options considered, decision, and consequences.
- See [ADR 0001: API-First with Bundled Web UI](adrs/0001-api-first-bundled-ui.md).
+438
View File
@@ -0,0 +1,438 @@
# FeDIY Open Questions
A living document of unresolved design and product questions. When a question is resolved, record the decision as an ADR and remove or archive the entry here.
Each question is tagged with the phase it blocks or most affects: [P0], [P1], [P2], [P3], [P4].
## Resolved Decisions
- A "project" is a defined work process.
- A project includes a list of materials/ingredients, a list of required tools, and step-by-step ordered instructions.
- Steps may include embedded media hosted on-instance or linked from external sources.
- Projects may include one or more external canonical links (for example homepage, repository, or source publication).
- Explicit project versioning is preferred and should be supported.
- A project is composable: FeDIY provides a minimal core model, and instances can tailor project detail via optional domain-specific extensions.
- FeDIY should not require first-party implementation of every domain detail up front; expert communities can define richer schemas over time.
- Materials are project-scoped entries with a fixed core shape: display name, structured quantity, unit, and optional note. Material entries are embedded within a project revision rather than modeled as independent top-level entities in Phase 1. Each material entry can carry the same extension payload mechanism as project extensions. Community-defined material type schemas (e.g. yarn, filament, PCB component) can be layered on without modifying the core model.
- Required tools are project-scoped entries with a lightweight core shape: display name and optional note. Tools are embedded within a project revision rather than modeled as independent top-level entities in Phase 1. Each tool entry can carry optional metadata such as skill level, safety notes, and alternatives. A shared tool taxonomy remains a future option, not a Phase 1 requirement.
- **Database: PostgreSQL is the primary persistence target.** JSONB, native full-text search, transactional consistency under concurrent federation fan-in, and broad managed hosting support make it the clear long-term fit. The persistence layer is behind a repository abstraction (trait-based interfaces), which keeps business logic independent of the database driver and leaves SQLite viable as a future lightweight self-hosting option without requiring changes to domain logic. See [ADR TBD: Persistence Layer Architecture].
- **Baseline content prohibitions (hardcoded, not operator-configurable):** CSAM, doxxing, and non-consensual intimate imagery (NCII) are prohibited on any FeDIY instance regardless of operator policy. The guiding principle is **consent**: minors cannot consent to sexual content; individuals have not consented to having their private identifying information published; subjects of intimate imagery have not consented to its distribution. Enforcement is in-code as far as technically feasible (hash-matching for CSAM and NCII; upload-time pattern detection and mandatory human-review tooling for doxxing). Weapons, violence, and similar dual-use content are **not** hardcoded prohibitions — legitimate DIY projects (fireworks, blacksmithing, knife-making) are indistinguishable at the software level and are handled by operator content policy and community moderation.
- **Personal data register (Q38):** Full register in ARCHITECTURE.md. Required registration fields: email, password hash, handle, display name, minimum-age-verified boolean (raw DOB discarded after age check). IP addresses never stored — ephemeral only. Optional profile fields (bio, avatar, header image, location, preferred crafts, pronouns, external links, locale, display preferences) all under contract. Analytics must be truly aggregate/anonymised — per-user event streams require consent. Handles are changeable with a redirect from old to new URL.
- **Project revision model (Q1):** Use immutable numbered revisions plus mutable drafts. Projects may reference other projects as reusable sub-processes or prerequisites, but recursive content is represented as a graph of project references rather than inline embedding of entire project bodies. Each publish action snapshots materials, tools, steps, media references, canonical links, extension payloads, and any project references as-of publish time. Full history is visible in the API and UI, with the latest published revision as the default view.
- **Federated material catalogs and shared vocabularies (Q2e):** Deferred to Phase 2/P3. Federated material type catalogs, tool registries, and other shared domain vocabularies as ActivityPub objects are a future option enabled by the current extension model, not a Phase 1 requirement. The typed JSON extension block mechanism (Q2c/Q2d) is designed to accommodate future federated catalog entries without requiring core schema changes. Authorization, governance, and RTBF semantics for federated community-curated catalogs will be explored in Phase 2+.
## Upfront Clarification Plan (P0 -> Early P1)
The goal is to remove ambiguity before implementation while keeping scope realistic.
1. Decision track A: Project revision model
- Resolve Q1 first.
- Output: one ADR defining draft/publish/supersede behavior and history visibility.
- Success signal: API and UI contracts can assume a stable project lifecycle.
1. Decision track B: Core-plus-extension contract
- Resolve Q2, Q2a, Q2b, Q2c, and Q2d as one coherent contract.
- Output: one ADR for core project and material fields, and one ADR for extension payload shape/namespacing/discovery (shared by both project and material extensions).
- Success signal: instances can add domain-specific detail at both the project level and the material entry level (knitting yarn specs, 3D filament profiles, electronics BoM entries, etc.) without changing core semantics.
1. Decision track C: Search/index policy for extensions
- Resolve the extension-indexing part of Q2c with Q23.
- Output: indexing policy doc or ADR that separates required indexed fields from opaque extension fields.
- Success signal: predictable search behavior across instances with different extensions.
1. Decision track D: API stability and evolution
- Resolve Q10 and Q11 before broad client development.
- Output: API versioning/deprecation policy with compatibility guarantees for third-party clients.
- Success signal: extension evolution does not break existing clients unexpectedly.
---
## Domain Model
**Q1 [P1]** ~~What should the explicit versioning model look like?~~ **RESOLVED — see Resolved Decisions and ARCHITECTURE.md Project Revision Lifecycle.**
Decision: immutable numbered revisions plus mutable drafts. Projects may reference other projects as reusable sub-processes or prerequisites, but recursive content is represented as a graph of project references rather than inline embedding of entire project bodies. Publishing freezes a revision snapshot; later edits create a new draft and then a new numbered revision. Full history is visible in API and UI, with the latest published revision as the default view.
**Q2 [P1]** ~~How are materials modelled?~~ **RESOLVED — see Resolved Decisions and ARCHITECTURE.md Project Domain Baseline.**
Decision: project-scoped material entries with a fixed core shape: display name, structured quantity, unit, and optional note. Material entries are embedded within a project revision rather than modeled as independent top-level entities in Phase 1. Each material entry can carry the same extension payload mechanism as project extensions. Community-defined material type schemas can be layered on without modifying the core model.
**Q2d [P1/P2]** What is the extension model for domain-specific material data?
~~Does a material entry carry the same extension payload mechanism as a project (namespaced typed block, discoverable schema)?~~ ~~Who can define a material type schema — instance operators only, or any community contributor who publishes a schema at a well-known URL?~~ ~~Should FeDIY ship a small set of reference material type schemas (yarn, 3D filament, electronic component) as non-mandatory examples to establish the pattern?~~ ~~How does a client know which material type extension(s) a given entry carries, and how does it fall back gracefully when it does not support the type?~~ ~~What is the relationship between project-level extensions and material-level extensions? Can a domain extension define both a project schema and a material schema that are versioned together?~~
Decision: yes - material entries use the same typed JSON extension block model as projects. Each material extension block has a namespace, type identifier, version, and payload; clients discover them from explicit material-entry metadata and preserve unknown optional blocks opaquely. Material type schemas may be published by instance operators or the community, and a shared material taxonomy remains a future option. A domain extension may define both a project schema and a material schema, versioned separately but named consistently.
**Q2e [P2/P3]** What would a federated material catalog look like? **RESOLVED — see Resolved Decisions above.**
**Q2a [P1]** How are required tools modelled?
~~Free-text tools list only, or a normalized/tool taxonomy strategy?~~ ~~Should tools support optional metadata (skill level, safety notes, alternatives)?~~
Decision: project-scoped tool entries with a lightweight core shape: display name and optional note. Tools are embedded within a project revision rather than modeled as independent top-level entities in Phase 1. Each tool entry can carry optional metadata such as skill level, safety notes, and alternatives. A shared tool taxonomy remains a future option, not a Phase 1 requirement.
**Q2b [P1]** How are canonical external links modelled and validated?
~~Single canonical link or multiple typed links (homepage, repository, video, reference)?~~ ~~Are external links version-scoped or project-scoped?~~ ~~What URL validation and safety checks are required?~~
Decision: multiple typed project-scoped links. A project can carry several canonical links such as homepage, source repository, build instructions, video walkthrough, and reference material. Links are project-scoped by default so they remain stable across revisions; a version-scoped link is allowed when a specific published revision needs its own source or artifact reference. Validation requires an allowed URL scheme, scheme-specific safety checks, and rejection of dangerous or nonsensical schemes.
**Q2c [P1/P2]** What is the extension model for domain-specific project data?
~~What extension shape is supported first: typed JSON blocks, namespaced key/value fields, or plugin-defined schemas?~~ ~~How are extensions identified and namespaced to avoid collisions across instances?~~ ~~How do API and UI clients discover which extensions are present on a project?~~ ~~Which extension fields are indexed for search, and which remain opaque?~~ ~~What validation guarantees does the server provide for extension payloads?~~
Decision: typed JSON extension blocks attached to a project revision. Each block has a stable namespace, a type identifier, a version, and a payload. Namespaces are collision-resistant (for example reverse-DNS or URL-based identifiers). API and UI clients discover extensions via explicit metadata on the project revision. Known extensions are validated against their schema; unknown optional extensions are preserved opaquely and round-trip through the API; unknown required extensions may be rejected until the instance supports them.
**Q3 [P1]** What is the tag and category strategy?
- Folksonomy (free-form user tags), curated taxonomy, or both?
- Is there a category hierarchy (craft type → technique → material)?
- Who controls the taxonomy on a given instance?
**Q4 [P1]** What licences can a project carry?
- Does the platform enforce a licence selection, or is it free-text?
- Does the platform's own CC BY-SA 4.0 licence apply to user content by default, or is that a separate question?
**Q5 [P3/P4]** What are the rules for project forks and remixes?
- Can a user fork another user's project (including from a remote instance)?
- Does a fork maintain a reference/attribution link to the original?
- What licence constraints apply to remixing?
---
## Identity and Authentication
**Q6 [P1]** What is the authentication mechanism?
- Local username/password (with secure hashing), passkeys, OAuth2/OIDC third-party providers, magic-link email, or a combination?
- Is email verification required for account creation?
**Q7 [P1]** What account fields are required beyond the ActivityPub actor minimum?
- Display name, bio, avatar, location — which are required, optional, or omitted entirely?
- Are there craft-specific profile fields (preferred crafts, skill level)?
**Q8 [P2]** Can remote ActivityPub actors interact without a local account?
- Can a remote actor follow a local user, like a project, or comment, without registering locally?
- What local data is persisted for a remote actor who interacts?
**Q9 [P1]** What is the session and token strategy for the API?
- Short-lived JWTs, opaque bearer tokens with a refresh flow, or server-side sessions?
- How are tokens invalidated (logout, account suspension)?
---
## API Design
**Q10 [P1]** What API style?
- REST with JSON, or something else (GraphQL, JSON:API)?
- Is there value in JSON:API's sparse fieldsets and relationship includes for a project-browsing use case?
**Q11 [P1]** What is the API versioning strategy?
- URL path prefix (`/api/v1/`), `Accept` header versioning, or no versioning until a breaking change forces it?
**Q12 [P1]** What is the pagination strategy?
- Cursor-based (stable under concurrent inserts), offset-based, or keyset pagination?
- What is the default and maximum page size?
**Q13 [P1]** What rate-limiting and abuse-prevention strategy applies to the API?
- Per-IP, per-authenticated-user, or both?
- Does this apply equally to federation endpoints?
---
## Front-End / Bundled UI
**Q14 [P1]** What technology powers the bundled web UI?
- Vanilla JS / progressive enhancement (HTMX or similar), a Rust WASM front-end framework, or a JS framework (e.g. Svelte, Vue)?
- Does the choice live in the same Cargo workspace or a separate directory with its own build tooling?
**Q15 [P1]** What is the no-JavaScript fallback scope?
- Read-only browsing (project pages, search results) without JS is desirable.
- Authoring without JS is probably out of scope — is that an explicit decision?
**Q16 [P1]** What is the accessibility baseline and implementation strategy?
- WCAG 2.1 AA is the minimum standard. How do we validate compliance and maintain it over time?
- What alt text strategy is required for all media (project images, step-by-step photos, diagrams, charts)? Do we enforce it at upload time or provide tools for post-hoc addition?
- What captions and transcripts strategy for audio/video content? Who is responsible for creation?
- What text-to-speech capabilities should be built into the API and UI? Should the API provide structured step data (title, description, images) in a format suitable for TTS clients?
- How do we support blind and low-vision users in the bundled UI? Screen reader testing and semantic HTML are baseline; what else?
- How do we support Deaf and hard-of-hearing users? Captions for instructional videos, visual indicators for audio cues, readable transcripts.
- How do we support users with motor differences? Full keyboard navigation, no time-dependent interactions, adjustable interface sizes/spacing.
- What color contrast requirements apply to project images and diagrams submitted by users? Can we provide tools or guidance to improve accessibility?
- Are there craft-community-specific accessibility concerns (e.g., tactile or kinesthetic learning for certain crafts, accessible alternatives for physical demonstrations)?
- What is the accessibility review process for features and content? How are accessibility issues prioritized?
**Q16a [P1]** What reading-comfort customization options does the bundled UI provide?
- What font choices are offered? At minimum, the UI should offer a dyslexia-friendly typeface (e.g., OpenDyslexic, Atkinson Hyperlegible) alongside a standard option.
- Should the full base font be user-overridable (including via browser/OS settings and user stylesheets)? The bundled UI must not block this.
- What line-height, letter-spacing, word-spacing, and paragraph-width adjustments are available? (Wide spacing and shorter line length aid many readers.)
- Are text size controls per-user and persistent (stored in account preferences), or session-only?
- Should there be a low-visual-stress color theme (off-white/cream backgrounds, reduced contrast)? Some users with dyslexia or visual stress find high-contrast black-on-white harder to read.
- How do user-defined display preferences interact with instance theming? User preferences must take precedence.
- Are reading-comfort settings exposed via API so third-party clients can retrieve and honor them?
**Q16b [P1]** What is the localization (i18n/l10n) strategy?
- What locale data format is used for UI strings? (gettext PO, JSON, TOML, ICU MessageFormat?)
- What is the language tagging convention for user-generated content? BCP 47 language tags are assumed — is this confirmed?
- Does the platform support RTL scripts (Arabic, Hebrew, Persian, etc.) from the first UI pass? CSS logical properties are required if so.
- What locale-sensitive formatting is required at MVP? (dates, times, numbers, units of measure)
- How are translations contributed by the community? Are translation files in the main repo or a separate project?
- What is the fallback behavior when a user's preferred locale is not available for a piece of content?
- Does the search index need locale-specific text analysis (stemming, tokenization) configured per language?
- Does the ActivityPub object for a project carry `@language` or equivalent metadata to signal content language to federated instances?
- Is machine translation (MT) in scope? If so, is it instance-opt-in, per-user opt-in, or always-on?
---
## Federation and ActivityPub
**Q17 [P2]** How do FeDIY project objects map to ActivityPub types?
- Use `Note` or `Article` for broad compatibility, or define a custom `FeDIYProject` type?
- If custom, what fallback representation do we provide for clients that don't understand it?
**Q18 [P2]** What ActivityPub activity types does FeDIY support in phase 2?
- Minimum set: `Create`, `Update`, `Delete`, `Follow`, `Accept`, `Reject`, `Undo`.
- Phase 2 or later: `Like`, `Announce` (boost), `Flag` (report)?
**Q19 [P2]** What is the media federation strategy?
- Do media attachments (images, files) federate as links to the canonical origin, or are they replicated locally?
- How are broken/unavailable remote media handled in the UI?
**Q20 [P2]** What is the HTTP Signatures key lifecycle?
- Per-actor keypairs (standard), or instance-level signing with `keyId` delegation?
- Key rotation: when and how are keys rotated, and how are remote instances notified?
**Q21 [P2]** Which well-known endpoints are in scope for phase 2?
- WebFinger (required for actor discovery).
- NodeInfo (instance metadata for compatibility and listing services).
- `/.well-known/oauth-authorization-server` if OIDC is supported.
**Q22 [P2]** How is WebFinger structured for FeDIY entities?
- Actors are users: `acct:user@instance` — standard.
- Do projects also have addressable AP identities, or do they belong to the author actor?
---
## Search and Discovery
**Q23 [P1]** What is the full-text search implementation?
- PostgreSQL full-text search (zero extra infra), an embedded engine (Tantivy via Rust), or an external service (Meilisearch, Elasticsearch)?
- What fields are indexed: title, description, steps, tags, materials?
**Q24 [P2]** Does search span federated content?
- Phase 1: local content only.
- Phase 2+: do we query remote instances, or build a local index of federated objects we've received?
---
## Media Storage
**Q25 [P1]** How are user-uploaded media assets stored?
- Local filesystem, S3-compatible object storage, or both with a configurable backend?
- What is the maximum file size and permitted formats for MVP?
**Q26 [P1]** Is image processing (resize, thumbnail, format conversion) in-process or delegated?
- In-process with a Rust image library, or delegated to an external service/worker?
---
## Persistence
**Q27 [P0/P1]** ~~What is the database?~~ **RESOLVED — see Resolved Decisions.**
Decision: PostgreSQL as primary target with a repository abstraction layer. SQLite is a possible future option (hobbyist self-hosting) enabled by the abstraction without changing business logic. Decision track: one ADR to cover the persistence layer architecture (database choice + repository pattern + query library selection).
**Q28 [P1]** What is the database migration strategy?
- A Rust migration library (sqlx migrate, refinery), or a standalone tool (Flyway, Liquibase)?
---
## Moderation
**Q29 [P1]** How are moderator roles assigned and scoped?
- Instance admin assigns moderators manually; no self-service promotion.
- Are there multiple moderation tiers (e.g. content moderator vs instance admin)?
**Q29a [P1]** What user-level personal moderation tools are provided, and how are they represented in the data model?
- A user must be able to block specific local and remote accounts without any moderator involvement. What is the API shape for a user-level block?
- A user must be able to block an entire remote instance. Does this map to an ActivityPub `Block` activity, a local filter record, or both?
- Are user-level mutes (suppress content without blocking) distinct from blocks in the data model?
- What keyword and wildcard filter capabilities are supported? Are filters applied server-side (content never delivered to client) or client-side (UI suppresses matching content)? Both options should be supportable.
- When a user blocks another, is the blocked party notified? (Convention in AP-based platforms is not to notify.)
- Do user-level blocks prevent the blocked party from seeing the user's public content, or only prevent interaction?
- How are user-level moderation actions represented in the user's own data export (GDPR portability)?
**Q29b [P1/P2]** What is the data model and AP representation for shareable block and recommendation lists?
- Shareable block lists: what format is used for export and import? JSON-LD? A well-known community format (e.g., Oliphant CSV, FediBlock)?
- Can a block list be published as a live federated resource that subscribers can follow and receive updates from?
- Recommendation lists: are these a first-class AP object type (e.g., `OrderedCollection` of `Project` objects), or a local-only feature?
- Personal collections/bookmarks: are these private by default with an explicit publish action, or public by default?
- What privacy model applies to list subscriptions? Can a user see who has subscribed to their block list?
- How does subscribing to another user's block list interact with the subscriber's own moderation decisions? (Additive by default; subscriber retains override.)
- Are community-maintained lists (collaboratively edited by a group) in scope, and if so, what is the authorship/edit governance model?
- Can lists be versioned or snapshotted so a subscriber can audit what changed between updates?
**Q30 [P3]** Do we participate in shared blocklists (e.g. FIRES, Oliphant tiers)?
- Subscribe to external block lists automatically, or manual import only?
- Is this a phase 3 concern or deferred entirely?
- Does the user-level list subscription mechanism (Q29b) subsume this, or is it a separate instance-level concern?
**Q31 [P3]** What is the user-facing report and appeals workflow?
- Can a user see the status of their own report?
- Is there a formal appeals process, or at moderator discretion?
---
## Deployment and Operations
**Q32 [P0/P1]** What is the primary deployment target?
- Single static binary + external PostgreSQL (simplest self-hosting).
- OCI/Docker container image.
- NixOS module.
- All three, or a prioritised subset?
**Q33 [P1]** What are the minimum self-hosting requirements?
- RAM, CPU, disk, and network minimums for a small instance.
- Is there a single-binary mode with embedded SQLite for hobbyist hosting (see Q27)?
**Q34 [P1]** What is the configuration strategy?
- Environment variables only, a config file (TOML), or both?
- What must be configurable per-instance (instance name, federation policy, storage backend, SMTP, etc.)?
**Q35 [P4]** What observability stack is expected?
- Structured logging to stdout (12-factor), Prometheus metrics endpoint, OpenTelemetry traces?
- Are these required at launch or added progressively?
---
## Content and Community Policy
**Q36 [P0]** ~~Does the platform define baseline content guidelines beyond what moderation tooling enforces?~~ **RESOLVED — see Resolved Decisions.**
Decision: CSAM, doxxing, and NCII are hardcoded prohibitions enforced in code as far as technically feasible. The guiding principle is consent. Weapons and dual-use DIY content are not hardcoded — handled by operator policy.
**Q37 [P4]** Are collaborative/co-authorship workflows in scope?
- Can multiple accounts be listed as co-authors of a project?
- Is there a contribution workflow (pull-request style) or trust-based co-author invite?
---
## Privacy and Legal Compliance
**Q38 [P0/P1]** What personal data does FeDIY collect and what is the lawful basis for each category?
**Q38 [P0/P1]** ~~What personal data does FeDIY collect and what is the lawful basis for each category?~~ **RESOLVED — see Resolved Decisions and ARCHITECTURE.md Personal Data Register.**
Decision: Full personal data register documented in ARCHITECTURE.md. Required registration fields: email, password hash, handle, display name, minimum-age-verified boolean (raw DOB discarded after age check). IP never stored. Optional profile fields under contract. Analytics must be truly aggregate/anonymised. Handles changeable with redirect.
**Q39 [P1]** What does the right-to-access (GDPR Article 15) export look like?
- What data categories are included in a user's full export: account profile, published projects, draft projects, interactions (follows, likes, bookmarks, block lists), moderation history affecting the user, session and audit records?
- What format is the export? JSON is required; is a human-readable HTML or PDF summary also provided?
- Is the export self-service (user-initiated via UI and API) or does it require admin action?
- What is the SLA for delivering an export? GDPR requires response within one month.
- How are exports of federated data handled — i.e. data about the user that exists on remote instances? The export must explain this limitation.
**Q40 [P1]** What does account deletion (GDPR Article 17 — right to erasure / right to be forgotten) entail?
- What is the deletion workflow? Must be self-service, not admin-gated.
- What data is fully erased: credentials, profile fields, private drafts, session tokens, email address, IP logs?
- What is tombstoned rather than erased: publicly published content that is referenced by others? The privacy notice must explain the tombstone policy.
- What moderation records are retained in anonymised form for legal/safety obligations, and for how long?
- How long after a deletion request is the data fully purged? A maximum window (e.g. 30 days) must be defined and disclosed.
- How is deletion propagated to federated instances (GDPR Art. 17(2))? An ActivityPub `Delete` activity is sent to known peers; remote compliance cannot be guaranteed. The privacy notice must say this.
- Is there a delivery-receipt log for `Delete` activities sent to federated peers, retained for operator accountability (separate from user personal data)?
- Is there a deletion-in-progress state visible to the user while federation propagation is completing?
- Does the architecture support deletion of individual published items (a single project, a comment) without requiring full account closure?
- Is legal hold (suspension of deletion during active investigation or legal proceedings) required? If so, how is the user notified?
- For financial/transaction records, what is the operator-configurable retention window to satisfy accounting law?
**Q40a [P1]** How does the platform support compliance with US state privacy laws alongside GDPR?
- CCPA/CPRA (California): deletion SLA is 45 days (extendable to 90). Does the system support configurable SLA windows per instance?
- CCPA/CPRA: right to opt-out of sale/sharing of personal data. FeDIY does not sell data, but does the architecture support the Global Privacy Control (GPC) signal as an opt-out mechanism?
- CCPA/CPRA: right to correct inaccurate personal information. Is this satisfied by standard profile editing?
- CCPA/CPRA: right to know (categories of data collected, sources, purposes, third parties). Is this satisfied by the privacy notice and data export?
- Virginia VCDPA, Colorado CPA, Connecticut CTDPA, Texas TDPSA and others: broadly equivalent deletion and portability rights with 45-day SLAs. Does the jurisdiction-agnostic deletion workflow satisfy all of these?
- Colorado CPA specifically: Global Privacy Control signals must be honored. Is GPC processing in scope for Phase 1?
- Brazil LGPD Article 18: right to deletion of unnecessary or unlawfully processed data, equivalent in scope to GDPR Art. 17. Is the architecture jurisdiction-agnostic enough to satisfy this without custom logic?
- Canada PIPEDA (and forthcoming CPPA / Bill C-27): limited right to deletion currently; architecture should anticipate the stronger rights in Bill C-27 when enacted. What future-proofing is needed?
- UK GDPR: equivalent to EU GDPR; same architecture satisfies it, but does the template privacy notice need UK-specific customisation (ICO contact details, UK law references)?
**Q40b [P1]** What is the operator guidance for jurisdiction-specific compliance customisation?
- Which compliance settings are configurable per-instance (SLA window, data categories, GPC handling, legal hold policy)?
- Does FeDIY provide a compliance checklist for operators launching a public instance?
- Does the template privacy notice include jurisdiction-specific variants (EU, UK, California, Brazil) or a single configurable template?
- How does FeDIY communicate clearly that the instance operator is the data controller and bears primary legal responsibility?
**Q41 [P1]** What are the data retention periods for each category?
- Authentication and failed-login logs: short retention (3090 days suggested); is this configurable by instance operators?
- IP address logs: are these stored at all beyond ephemeral request processing? If so, what is the maximum retention window?
- Deleted account data: what is the maximum time between deletion request and full purge of identifiable data?
- Moderation records: anonymised retention for legal purposes — what anonymisation process is applied and for how long are they kept?
- Inactive account data: is there a policy for purging accounts that have never been activated or have been dormant for an extended period?
**Q42 [P1]** What is the data portability (Article 20) export format, and can it be imported?
- Is the export format capable of round-tripping into another FeDIY instance (i.e. migrate your account and projects to a different instance)?
- Does the export include ActivityPub actor identity in a way that helps federated peers update their records after a migration?
- Is account migration (move actor from instance A to instance B, with follower redirect) in scope? If so, which phase?
**Q43 [P0/P1]** What is the privacy notice strategy for instance operators?
- FeDIY provides a template privacy notice that operators must customise. What is the minimum required content?
- Is the privacy notice served at a well-known URL (`/privacy`) before the instance accepts registrations?
- How does the platform ensure that operators have published a privacy notice? (e.g. configuration check at startup, NodeInfo metadata)
- Who is the data controller for a self-hosted instance? The instance operator. Is this clearly communicated in the code and documentation?
**Q44 [P1]** What is the children's privacy policy?
- What minimum age is required to register? (GDPR requires parental consent for under-16 in most EU member states; COPPA requires age 13 in the US.)
- Is age verification self-declaration only, or is a stronger mechanism required?
- What happens if a minor's account is reported? Is there a defined response process?
**Q45 [P2]** How are federated data subjects' rights handled?
- If a user on a remote instance requests erasure of data held locally (e.g. cached profile, received activities), what is the process?
- Does receiving a `Delete` activity for a remote actor trigger a purge of all locally cached data about that actor?
- Are there GDPR obligations that apply to data received via federation from instances in different jurisdictions?
+11
View File
@@ -0,0 +1,11 @@
# FeDIY Planning Docs
This directory contains product and technical planning documents for FeDIY.
- [Roadmap](ROADMAP.md): phased milestones from MVP to broader federation support.
- [Architecture](ARCHITECTURE.md): system boundaries, components, and design constraints.
- [Workflow](WORKFLOW.md): Red-Green TDD/BDD delivery model and feature-branch workflow with pull request review.
- [Open Questions](OPEN_QUESTIONS.md): unresolved design and product decisions, tagged by phase.
- [ADRs](adrs/): architecture decision records.
These docs are intended to evolve as priorities change.
+124
View File
@@ -0,0 +1,124 @@
# FeDIY Roadmap
This roadmap prioritizes a usable core product first, then federation depth and community scaling.
## Product Intention
Build a federated DIY project-hosting platform in Rust, inspired by the utility of Ravelry and Instructables, but interoperable through ActivityPub.
## Phase 0: Foundations
Goals:
- Stabilize development environment and reproducible tooling, while keeping the contributor path usable for people who do not use Nix.
- Define domain language and baseline architecture docs.
- Establish quality process (TDD/BDD + feature-branch workflow with pull request review).
- Clarify the core-plus-extension project contract before implementation.
- Define personal data categories, retention windows, and erasure obligations before any user data model is implemented.
Exit criteria:
- Agreed glossary and architecture baseline.
- Documented contribution and branch workflow.
- Gitea Actions CI pipeline in place for formatting, linting, and tests.
- Documented onboarding path for non-Nix contributors using standard Rust toolchain commands.
- ADR for project revision lifecycle (draft/publish/supersede).
- ADR for composable extension mechanism (shape, namespacing, discovery).
- ADR for persistence layer architecture (PostgreSQL as primary target; repository abstraction pattern; query library selection; SQLite future-option strategy).
- Documented container packaging path (OCI/Docker image build/run flow and configuration contract) alongside existing Nix and Flatpak targets.
- Periodic packaging/tooling review policy so the flake and shell environments stay aligned with active roadmap phases and do not accumulate stale dependencies.
- Initial repository layout includes dedicated locations for API contracts and extension schemas.
- Documented answer to Q38: personal data categories and lawful basis for each (prerequisite for any user data model work).
- Draft privacy notice template and operator guidance (prerequisite for any public-facing instance).
## Phase 1: Single-Node MVP (No Federation Yet)
Goals:
- User identity and basic authentication model.
- Core DIY project entities (project, materials, tools, steps, media, canonical links, tags).
- Basic publishing lifecycle (draft, published, updated).
- Search and browse within one instance.
- Support extension payloads in project data model without requiring domain-specific first-party implementations.
- Support extension payloads on material entries using the same extension mechanism, enabling domain-specific material attributes (yarn weight, filament profile, component spec) without changing the core material record.
- User-level personal moderation: block and mute individual accounts; keyword and wildcard content filters. No moderator approval required.
- Personal collections and bookmarks (private by default).
- Self-service data export (right to access) and account deletion (right to erasure) with defined retention and purge windows.
Exit criteria:
- A user can publish and update a complete project end-to-end.
- Project pages are discoverable and readable on one node.
- Test coverage exists for core behavior paths.
- At least one project-level extension payload can be stored, validated, and rendered as non-breaking optional data.
- At least one material-level extension payload can be stored, validated, and rendered as non-breaking optional data.
- A user can block another user and have that block take effect immediately without moderator involvement.
- A user can bookmark and organize projects into personal collections.
- A user can export all their personal data without admin involvement.
- A user can delete their account without admin involvement; defined data purge window is enforced.
- Data retention windows for authentication logs, session tokens, and IP records are implemented and documented.
## Phase 2: ActivityPub Foundation
Goals:
- Implement canonical actor and object mapping.
- Add outbox/inbox behavior for core project publication events.
- Add HTTP Signatures and key lifecycle strategy.
Exit criteria:
- Instance can send and receive baseline ActivityPub messages for supported objects.
- Signature validation and delivery retry logic are documented and tested.
- Interop checks completed against at least one external implementation target.
## Phase 3: Federation UX and Safety
Goals:
- Federation-aware project discovery and attribution.
- Local moderation controls for remote content and actors.
- Abuse-report and review workflow for moderators.
- User-level block and mute extended to remote actors and instances (no moderator gate).
- Shareable and subscribable block lists and recommendation lists as federated first-class objects.
- Public personal collections with AP identities.
Exit criteria:
- Moderators can block/mute remote actors and instances.
- Remote project visibility follows local moderation policy.
- Audit trail exists for moderation decisions.
- A user can block a remote actor or entire instance without moderator involvement.
- A user can publish a block list or recommendation list and another user on any instance can subscribe to it.
## Phase 4: Community Scaling
Goals:
- Collaborative project patterns (forks/remixes, references, revisions).
- Better onboarding, templates, and curation flows.
- Operational hardening (backups, observability, incident playbooks).
Exit criteria:
- Multi-contributor workflows are clear and reliable.
- Admin operations are documented with tested recovery drills.
- Performance and reliability SLOs are defined and measured.
## Moderation Model Milestones
- Milestone A: Local content moderation for local users, plus user-level blocks/mutes/keyword filters (no moderator gate).
- Milestone B: Remote actor and instance policy enforcement; user-level blocks extended to remote actors and instances.
- Milestone C: Shareable and subscribable block lists and recommendation lists as federated objects.
- Milestone D: Transparent moderation history and appeals guidance; community-maintained shared lists.
## Federation Strategy Milestones
- Milestone A: Strictly scoped protocol subset with explicit compatibility statement.
- Milestone B: Progressive support for richer activity types.
- Milestone C: Interop matrix and periodic federation health review.
## Review Cadence
- Revisit priorities every 2 weeks.
- Re-scope phases quarterly based on delivery and federation feedback.
+57
View File
@@ -0,0 +1,57 @@
# Development Workflow
This project uses Red-Green TDD/BDD and feature-branch workflow with pull request review.
## Red-Green TDD/BDD Cycle
For each behavior increment:
1. Red: describe behavior with a failing specification/test.
2. Green: implement the smallest change needed to satisfy behavior.
3. Refactor: improve structure while keeping behavior unchanged.
BDD intent:
- Express behavior in user-meaningful terms.
- Prefer scenario-oriented acceptance criteria before implementation details.
- Keep unit and integration tests aligned with documented behavior.
Definition of done for a change:
- Behavior is specified and verified.
- Relevant tests are passing.
- Refactoring has preserved behavior.
- Documentation is updated when contracts or workflows change.
## Feature-Branch Workflow
Use short-lived branches from main.
Branch pattern examples:
- feature/<topic>
- fix/<topic>
- docs/<topic>
- chore/<topic>
Branch workflow:
1. Create branch from latest main.
2. Commit small, reviewable increments.
3. Open pull request early.
4. Keep branch current with main.
5. Merge after review and checks pass.
6. Delete merged branch.
## Pull Request Expectations
- Clear behavior statement and acceptance criteria.
- Test evidence for the behavior change.
- Notes on any architectural or moderation impact.
- Scope limited to one cohesive change.
## Agent Collaboration Rules
- Agents may support test planning, scenario writing, and review checklists.
- Agents must not generate executable core project code.
- For implementation guidance, agents should link primary sources and provide paraphrased walkthroughs.
+28
View File
@@ -0,0 +1,28 @@
# ADR 0001: API-First Architecture with Bundled Web UI
## Status
Accepted
## Context
FeDIY needs to serve both a usable web interface for end users and the ActivityPub federation protocol for other instances. It must also not create barriers to third-party clients or alternative front-ends. Without an explicit policy, it is easy to accumulate shortcuts where the bundled UI is given privileged access to server internals, making it progressively harder for external clients to reach parity.
## Options Considered
1. **Server-side rendering only** — simpler initial delivery but couples the front-end tightly to server internals, making third-party clients second-class.
2. **Separate front-end service** — clean decoupling but adds operational complexity and a cross-origin story from day one.
3. **API-first with bundled UI as first-party client** — the server exposes a stable public API; the bundled UI is a client of that API, co-deployed as static assets from the same origin.
## Decision
Option 3. The server exposes a stable HTTP API as its primary interface. The bundled web UI is a first-party client of that API and receives no privileged access unavailable to third-party clients. The UI is delivered as static assets from the same origin and is optional at deploy time.
## Consequences
- Every capability must be reachable through the public API before the bundled UI uses it. This creates a useful constraint that keeps the API complete.
- Content negotiation (ActivityPub vs JSON API) is required at the same URL namespace.
- CORS policy must be explicit and safe by default.
- Third-party clients and alternative front-ends are supported without server changes.
- The bundled UI serves as the reference implementation for API usability validation.
- The API surface must be versioned and changes must follow a deprecation policy.
View File
View File
+66 -47
View File
@@ -1,5 +1,5 @@
{
description = "A Nix-flake-based Rust development environment";
description = "FeDIY: a federated ActivityPub DIY platform built in Rust";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
@@ -36,7 +36,7 @@
templates = {
default = {
path = ./.;
description = "Rust dev environment using fenix; includes a skeletal Cargo project and packaged helper app";
description = "FeDIY Rust development environment and package outputs; Nix is optional for contributors";
};
};
@@ -59,32 +59,39 @@
{ pkgs }:
{
default = pkgs.mkShell {
packages = with pkgs; [
rustToolchain
git
gnumake
openssl
pkg-config
cargo-deny
cargo-edit
cargo-watch
cargo-generate
rust-analyzer
rustup
# Embedded Rust tooling
probe-rs-tools
espflash
openocd
minicom
# RP2040 UF2 workflows
elf2uf2-rs
picotool
avrdude
pkgsCross.avr.buildPackages.libc
pkgsCross.avr.buildPackages.gcc
ravedude
pre-commit
];
packages =
with pkgs;
[
# Rust toolchain (managed by fenix overlay)
rustToolchain
rust-analyzer
# Build essentials
git
gnumake
openssl
pkg-config
# Local database tooling
postgresql
# Localization tooling
gettext
# Browser and accessibility testing
chromium
playwright
# Cargo productivity tools
cargo-deny
cargo-edit
cargo-watch
# Code quality
pre-commit
# Packaging
flatpak-builder
]
++ lib.optionals pkgs.stdenv.isLinux [
# OCI/container tooling (Linux host only)
podman
podman-compose
buildah
];
env = {
# Required by rust-analyzer
@@ -98,20 +105,15 @@
echo " Initialized git repository"
fi
# Ensure user's Cargo-installed binaries are available
export PATH="$HOME/.cargo/bin:$PATH"
if command -v rustup >/dev/null 2>&1; then
echo "Ensuring common embedded Rust targets are available (idempotent)..."
rustup target add thumbv6m-none-eabi >/dev/null 2>&1 || true # Cortex-M0/M0+ (RP2040)
rustup target add thumbv7em-none-eabihf >/dev/null 2>&1 || true # Cortex-M4F/M7F (many STM32/nRF52)
rustup target add riscv32imc-unknown-none-elf >/dev/null 2>&1 || true
rustup target add riscv32imac-unknown-none-elf >/dev/null 2>&1 || true # ESP32-C3 class
echo "Note: ESP32 Xtensa targets require espup/custom toolchains (see esp-rs)."
echo "[FeDIY] Welcome to the dev shell!"
echo "Nix is optional for contributors. This shell is here if you want a ready-made toolset."
echo "Start with 'cargo build'. Use 'nix run .#dev-helper' for a quick task summary."
echo "Tools: cargo, rustc, clippy, rustfmt, rust-analyzer, flatpak-builder, psql, gettext, chromium, playwright"
echo "Packaging note: the shell is intentionally reviewed and trimmed as the roadmap changes."
if command -v podman >/dev/null 2>&1; then
echo "OCI tools: podman, podman-compose, buildah"
fi
echo "[rust-template] Welcome to the Rust dev shell!"
echo "Tools: cargo, rustc, clippy, rustfmt, rust-analyzer, probe-rs, espflash, openocd, minicom, elf2uf2-rs, picotool, avrdude, ravedude"
echo "Run 'cargo build' to build, or 'nix run .#dev-helper' for a tool summary."
echo "Run 'cargo build' to build, 'cargo test' to test, or 'make flatpak-build' for Flatpak."
echo "See README.md for usage."
'';
};
@@ -121,19 +123,36 @@
packages = forEachSupportedSystem (
{ pkgs }:
{
# Build the skeletal Cargo project
# Build the FeDIY Cargo project
default = pkgs.rustPlatform.buildRustPackage {
pname = "sample-rust-app";
pname = "fediy";
version = "0.1.0";
src = ./.;
cargoLock.lockFile = ./Cargo.lock;
meta.mainProgram = "fediy";
};
devHelper = pkgs.writeShellScriptBin "dev-helper" ''
echo "Rust toolchain available:"
command -v cargo >/dev/null 2>&1 && cargo --version || true
command -v rustc >/dev/null 2>&1 && rustc --version || true
echo "This binary is built by Nix (packages.default)."
echo "=== FeDIY dev shell tools ==="
echo "Build + Rust"
command -v cargo >/dev/null 2>&1 && echo " cargo: $(cargo --version)" || echo " cargo: not found"
command -v rustc >/dev/null 2>&1 && echo " rustc: $(rustc --version)" || echo " rustc: not found"
command -v rust-analyzer >/dev/null 2>&1 && echo " rust-analyzer: $(rust-analyzer --version)" || echo " rust-analyzer: not found"
echo "Testing + quality"
command -v pre-commit >/dev/null 2>&1 && echo " pre-commit: $(pre-commit --version)" || echo " pre-commit: not found"
command -v flatpak-builder >/dev/null 2>&1 && echo " flatpak-builder: $(flatpak-builder --version)" || echo " flatpak-builder: not found"
echo "Data + localization"
command -v psql >/dev/null 2>&1 && echo " psql: $(psql --version)" || echo " psql: not found"
command -v gettext >/dev/null 2>&1 && echo " gettext: $(gettext --version | head -n 1)" || echo " gettext: not found"
echo "Accessibility + browser checks"
command -v chromium >/dev/null 2>&1 && echo " chromium: $(chromium --version)" || echo " chromium: not found"
command -v playwright >/dev/null 2>&1 && echo " playwright: $(playwright --version)" || echo " playwright: not found"
if command -v podman >/dev/null 2>&1; then
echo "Container tooling"
echo " podman: $(podman --version)"
command -v podman-compose >/dev/null 2>&1 && echo " podman-compose: $(podman-compose --version)" || echo " podman-compose: not found"
command -v buildah >/dev/null 2>&1 && echo " buildah: $(buildah --version)" || echo " buildah: not found"
fi
'';
}
);
+6 -5
View File
@@ -1,20 +1,21 @@
{
"app-id": "org.example.rustdevshell",
"app-id": "com.moturpin.fediy",
"runtime": "org.freedesktop.Platform",
"runtime-version": "23.08",
"sdk": "org.freedesktop.Sdk",
"command": "rustdevshell-app",
"command": "fediy",
"modules": [
{
"name": "rustdevshell-app",
"name": "fediy",
"buildsystem": "simple",
"build-commands": [
"cargo build --release"
"cargo build --release",
"install -Dm755 target/release/fediy /app/bin/fediy"
],
"sources": [
{
"type": "dir",
"path": "../src"
"path": ".."
}
]
}
+3 -3
View File
@@ -1,6 +1,6 @@
[project]
name = "rust-template"
description = "A reusable Nix flake template for Rust development."
name = "FeDIY"
description = "A federated ActivityPub DIY project-hosting web application in Rust."
version = "0.1.0"
authors = ["gooba42 <your@email>"]
license = "MIT"
license = "CC-BY-SA-4.0"
View File
View File
+1
View File
@@ -8,6 +8,7 @@ pkgs.mkShell {
pkgs.rustfmt
pkgs.clippy
pkgs.rust-analyzer
pkgs.postgresql
];
shellHook = ''
echo "[shell.nix] Legacy shell for Rust dev. Use 'nix develop' for full flake support."