Expand description
The single owner of project behaviour (mission
first-class-projects-01M3BYBW, WP02).
Everything about a project lives here: identity and resolution, the registry lifecycle (create / edit / delete / list), derived membership and the index that makes a project filter a bucket lookup, the association mutations, and missing-reference diagnosis. Surfaces call this rather than re-deriving, because a second identity resolver or a stored membership index is exactly the divergence the mission’s charter escalates (C-006, NFR-001).
§What this module deliberately does not do
- It touches no files. It takes an in-memory
Configand an in-memory issue set, and returns values. Storage owns the write; this module owns the rule. The whole surface is therefore testable with noStoreand notempfile(T010 step 4). - It does not know about the issue model.
ProjectNodeis the minimum an issue must expose — its number, title, status, and itsprojectsid list — and WP03 implements it forcrate::model::Issueinsrc/model.rs(this mission’s WP03 owns that file), exactly as the hierarchy service’sHierarchyNodeis implemented there. WP02 is forbidden from touchingsrc/model.rs, so the service is defined against the shape WP03 provides. - It never mutates or returns a whole
Issue.associateanddissociatereturn aProjectChange: the resulting association list plus the History event to append. Storage applies it. That is the boundary that keeps this module model-free. - It stores no membership. A project’s members are derived by inverting the issues’ association lists, never persisted (data-model §4, C-003).
- It does not compute progress or health.
ProjectProgressandProjectHealthare WP04’s, added to this module additively; the singlehealthoperation the contract names lands there (contract §2).
§The index is built once per read
ProjectIndex is the derived view over one snapshot. It is built once
(ProjectIndex::build) and every read — ProjectIndex::membership,
ProjectIndex::resolve, ProjectIndex::missing — reads that one value
rather than rebuilding. The contract’s free operations each build exactly one
index per call, so a filter is a bucket lookup rather than a scan (NFR-001).
§Ordering is deterministic
Members are ordered by issue number, projects by declaration order, and
missing references by (issue number, project id), so repeated reads of the
same snapshot are identical (contract §6).
Structs§
- Bulk
Project Outcome - The per-issue outcome of a bulk association (contract §1).
- Issue
Key - A project issue number, as the derived structures key it.
- Member
Ref - One member of a project, with its derived display label.
- Missing
Project Reference - A stored association whose project is not in the registry (data-model §3).
- NewProject
- The spec for a new project.
- Project
- The service-side view of a project (data-model §2).
- Project
Change - The outcome of an association mutation: the resulting list plus the event.
- Project
Deletion - The impact report of a project deletion (contract §1).
- Project
Edit - The fields of a project edit.
- Project
Event - One association mutation, ready for storage to append to
## History. - Project
Health - A project’s health counters (data-model §5, FR-003).
- Project
Health Report - The typed value the
healthoperation returns (contract §1). - Project
Index - The derived project view over one snapshot of issues and the registry.
- Project
Membership - The derived members of a project (data-model §4).
- Project
Progress - A project’s completion progress (data-model §5, FR-003).
Enums§
- Patch
- One field edit: leave it, clear it, or set it.
- Project
Diagnostic Kind - The diagnostic kinds
contracts/project-service.md§1 names, spelled exactly. - Project
Error - Why a project operation was refused.
- Project
Event Kind - The two association mutations, as the
## Historysection records them.
Constants§
- MISSING_
REFERENCE_ KIND - The lint diagnostic kind for an association that no longer resolves.
- MULTIPLE_
PROJECTS_ BUCKET - The single bucket for an issue in several projects.
- NO_
PROJECT_ BUCKET - The clearly labelled bucket for an issue in no project.
- PROJECTS_
KEY - The frontmatter key carrying an issue’s project associations.
Traits§
- Health
Node - The one per-issue fact project health reads beyond
ProjectNode. - Project
Node - The minimum an issue must expose for project derivation.
Functions§
- assigned_
keys - The members of a snapshot that carry an assignee.
- associate
- Associate an issue with a project, producing the change and its History event.
- association_
detail - The single wording for an association change’s
## Historydetail line. - bulk_
associate - Associate each selector independently, reporting every outcome.
- create_
project - Create a project, allocating a fresh stable id (FR-001).
- delete_
project - Remove a project from the registry, reporting the issues that reference it.
- dissociate
- Remove an issue’s association with a project.
- duplicate_
name_ reason - The single wording for a project name refusal.
- edit_
project - Edit a project’s fields by reference.
- health
- Progress and health for a project, in one index build (contract §1).
- invalid_
dates_ reason - The single wording for a project date refusal.
- list_
projects - The projects in declaration order, with derived member counts.
- membership
- The ordered membership of a project, by id or name.
- membership_
index - Build the reverse index once for one read (
HashMap<ProjectId, Vec<IssueKey>>). - missing_
reference_ reason - The single wording for an association that no longer resolves.
- project_
bucket_ label - The group-section label for one issue’s resolved project memberships.
- project_
display - The shared display form for a project:
Platform hardening (p-3f9a2c). - resolve
- Resolve a project by id (first) or by name.
- resolve_
project_ id - Resolve a project id from a reference: id first, then a name convenience.
- unknown_
issue_ reason - The single wording for an issue selector that names no issue.
- unknown_
project_ reason - The single wording for an unresolvable project reference.
- validate_
references - Every association in the snapshot whose project is not in the registry.