# S1-whole-surface — findings

| | |
| --- | --- |
| Reviewer | Raheem takes the decisions; Zayed records them and locks |
| Reviewed | — |
| Status | draft |
| Supersedes | — |
| Superseded by | — |

**The outcome cells below are deliberately empty. The reviewer fills them.**
Everything else — the decisions, the options, the evidence and the write-back
destination each answer lands in — is already in place, so recording an answer
is a sentence, not a research task.

Read this with the prototype open. Every screenshot named here is reproducible
by pasting its URL, and the switch that produced it is in the bar under the
prototype header on the screen itself.

## Outcome per decision

"Outcome" is the answer chosen, in a sentence. "Evidence" is the screenshot the
answer rests on. A decision with no evidence is not settled.

| Id | Decision | Options built | Outcome | Evidence | Writes back to |
| --- | --- | --- | --- | --- | --- |
| S1 | What are the top-level navigation entries, and do the scaffold's seven survive the arrival of needs, notifications and administration? | a) a rail with grouped entries b) a top bar with an overflow | | `screenshots/index--default--ar.png`, `screenshots/index--default--ar--topbar.png`, `screenshots/index--default--ar--mobile.png`, `screenshots/index--default--ar--agent.png` | (c) a convention in the web repository |
| S2 | Is administration a different visual world, or the same shell with a different navigation group? | a) same shell, admin group b) its own chrome with a way back | | `screenshots/admin--default--ar.png`, `screenshots/admin--default--ar--separate.png`, `screenshots/admin--default--en.png` | (c) a convention in the web repository |
| S3 | Where does the club area live? | a) one entry opening an area with its own sub-navigation b) five top-level entries | | `screenshots/index--default--ar.png`, `screenshots/index--default--ar--flat.png`, `screenshots/club--default--ar.png`, `screenshots/club-structure--default--ar.png` | (c) a convention in the web repository |
| S4 | What shape is an approach — a thread, a record, or a row on a board? | a) thread b) record with a history c) board by state | | `screenshots/requests--default--ar.png`, `screenshots/requests--record--ar.png`, `screenshots/requests--board--ar.png`, `screenshots/offer--default--ar.png`, `screenshots/offer--record--ar.png` | (a) epic **A3.2**, and (c) a convention |
| S5 | What does a signed-in user land on? | a) the work waiting on them b) a launcher, one card per area | | `screenshots/index--default--ar.png`, `screenshots/index--launcher--ar.png`, `screenshots/index--empty--ar.png` | (a) epic **A1.0**, and (c) a convention |
| S6 | What is the one denial pattern, used for all four refusals? | a) in place, the context intact b) a screen of its own | | `screenshots/club--no-permission--ar.png`, `screenshots/club--no-permission--ar--page.png`, `screenshots/offer--no-permission--ar.png`, `screenshots/need--default--ar.png`, `screenshots/admin--no-permission--ar.png`, `screenshots/entitlements--error--ar.png` | (c) a rule for the code repository |

### Secondary questions the same screens answer

Not decisions of their own, but the review should not close without an answer,
because each has a write-back destination waiting for it.

| Question | Outcome | Evidence | Writes back to |
| --- | --- | --- | --- |
| An entry an account never holds — the agency, administration — is it absent from the navigation, or present and disabled so its owner knows it exists? | | `screenshots/index--default--ar--agent.png`, `screenshots/agent--default--ar.png` | (c) a convention |
| Notifications have a bell in the chrome **and** an entry in the navigation. Is the bell enough? | | `screenshots/notifications--default--ar.png`, `screenshots/index--default--ar.png` | (b) note on **A1.0** |
| Is the unread count one number everywhere — chrome, navigation entry, page head — or may a surface compute its own? | | `screenshots/notifications--default--ar.png` | (a) epic **A1.0** |
| May the landing carry any number that is not a count of clickable work? | | `screenshots/index--default--ar.png`, `screenshots/index--empty--ar.png` | (c) a convention |
| A private field a viewer's tier does not reach: is the locked placeholder the same pattern as a refusal at a smaller size, or a different thing? | | `screenshots/need--default--ar.png` vs `screenshots/need--private--ar.png` | (b) note on **A1.5** |
| Does the refusal read as well in dark as in light, given that the destructive colour is the only thing marking it? | | `screenshots/offer--no-permission--ar--dark.png` | (c) a convention |
| The board has five columns, and at 1280 with the rail the fifth wraps to a second row. Is a five-state board a shape the product can carry? | | `screenshots/requests--board--ar.png` | (b) note on **A3.2** |
| The club's own read of a need's applications shows the applicant's salary band locked. Is that the right answer, given the club published the need? | | `screenshots/need--default--ar.png` | (b) note on **A3.7** |
| The roster's third queue — people with no contract recorded — is the only place the club is told its own data is incomplete. Is one queue enough, or does the landing owe it a line? | | `screenshots/club-roster--partial--ar.png`, `screenshots/index--default--ar.png` | (b) note on **A2.6** |
| The contract end date is hidden from a visitor on the public squad list, though a signed-in user reads it by tier. Is a visitor's squad list exactly name, number and position? | | `screenshots/public--default--ar.png` | (b) note on **A5.1** |
| A dependency refusal turns on neither a permission nor a tier, and still wears the S6 shape. Does the one pattern stretch that far? | | `screenshots/entitlements--error--ar.png` | (b) note on **A4.1** |

---

# Write-back

Three destinations, one section each. Everything below is copy-paste ready.
Leave a section empty rather than inventing an entry for it.

**No requirement id from any parked requirement document may appear anywhere
below.** Restate it in the project's own words or drop it.

## The exact story format

Every story appended under (a) is **two lines**, the second indented by two
spaces, and nothing else:

```
- **As a <actor>**, I <do>, so that <outcome>.
  - Accept: <criteria>.
```

Rules the format does not show but the manifest enforces:

- Stories are **append-only**. Add to the end of that epic's `## Stories`
  block; never reorder, renumber or reword a story already there, because
  `story_notes` points at stories by their 1-based position.
- `<actor>` matches the actors already used on that epic — "any signed-in user"
  on A1.0, "club user" on A3.1 and A3.2, "club user of an approved club" on
  A3.7, "club admin" on A2.3 and A2.6, "platform admin" on A0.13.
- One `Accept:` line, one sentence, testable. If it needs two sentences it is
  two stories.
- The story says what the user does, not which component renders it.

## (a) New stories

Written only for the outcomes that change what an endpoint must return. An
information-architecture answer that changes no payload goes to (c) instead.

### Epic `A1.0` — Notification centre — from the **S5** and **unread count** findings

Append only if the reviewer answers S5 with the work queue, and only in the
shape below. The landing reads from more than one epic, so the story belongs to
the epic that already owns "what happened to me and what do I owe".

```
- **As any signed-in user**, I read one count of the work waiting on me wherever the product shows it, so that the badge, the navigation entry and the screen never disagree.
  - Accept: the unread and outstanding counts come from one endpoint, and no surface computes its own.
```

### Epic `A3.2` — Offer lifecycle and deal types — from the **S4** finding

Append only if the reviewer answers S4 with the board, because a board needs
the state and the counts per state on the list endpoint and a thread does not.

```
- **As a club user**, I see every approach my club has open grouped by its state with a count on each group, so that I can read the club's whole position at once.
  - Accept: the list endpoint returns the state of each approach and the count per state, and the states are exactly the ones the offer state machine enforces.
```

### Epic `A3.7` — Club needs and applications — from the **applications** finding

Append only if the reviewer decides the club that published a need reads an
applicant at a tier other than its own.

```
- **As a club user of an approved club**, I read an applicant to my need at exactly the tier I hold anywhere else, so that publishing a need never becomes a way to read more than I am entitled to.
  - Accept: an application's payload applies the same visibility rules as a profile read, and no field is added by the act of applying.
```

## (b) Notes on existing stories

Keyed by the story's 1-based position in that epic's `## Stories` block. Merge
into the epic's `story_notes` object; do not replace it.

```json
"story_notes": {
  "<n>": "partial: <what the prototype found about that story>."
}
```

| Epic | Story position | Which story it is | Note |
| --- | --- | --- | --- |
| A1.0 | | the inbox with the unread badge | |
| A1.5 | | the basic-tier viewer meeting a private field | |
| A2.6 | | the roster rows with no contract recorded | |
| A3.2 | | the offer thread from both sides | |
| A3.7 | | reviewing the applications on a need | |
| A4.1 | | the module registry with its dependency check | |
| A5.1 | | the anonymous club and squad pages | |

## (c) Rules and conventions for the code repository

Recorded with the `record-rule` tool for a code repository's `.ai/rules/`; an
information-architecture decision that belongs to no epic becomes a convention
in the web repository's `CLAUDE.md` instead, which is where most of S1's
outcomes land.

| Glob | Title | Note |
| --- | --- | --- |
| | | |

Candidate rules and conventions this prototype surfaced, for the reviewer to
accept or drop. Each is written as it would read once accepted:

1. **The navigation is one list with groups, and an entry an account does not
   hold does not exist for it.** The final entry list is S1's outcome; today's
   scaffold guesses seven and this prototype renders ten, two of them
   conditional. Whichever wins, the list lives in one place and every screen
   reads it.
2. **Administration is [S2's answer].** If it is the same shell, a screen that
   writes reference data for the whole platform says so on the screen. If it is
   its own shell, it carries only administration entries and always offers the
   way back.
3. **The club is [S3's answer].** If it is an area, its name and its status sit
   at the head of every screen inside it, and no club screen repeats them. If
   it is five entries, each of the five carries the club's status itself,
   because a pending club must never reach a transaction without being told.
4. **An approach is [S4's answer] on the detail, and [S4's answer] in the
   list.** The states are the ones the server enforces — sent, under review,
   countered, accepted, rejected, withdrawn — and are never configurable by a
   club.
5. **The landing carries no number that is not a count of clickable work.** No
   profile views, no followers, no interactions, no trend. Every number on it
   opens onto rows, and every row offers the action it is about.
6. **Every refusal names what was refused, the rule that refused it, the date it
   changes where one exists, and the one thing to do next.** The shape is
   [S6's answer] and it is the same shape for an eligibility refusal, a pending
   club, a route a role may not open, and a missing module dependency.
7. **A field a viewer's tier does not reach keeps its place and names the
   tier.** It never collapses, because a gap reads as "no data" and that is a
   different fact.
8. **Dates inside an Arabic sentence use a month name, never the ISO form**, and
   a refusal that names a date obeys this too. (Carried from P1; S1 adds that a
   refusal is exactly where it matters most.)

---

## Rejected options

What was tried and abandoned, and why — filled by the review. This is the part
that stops the same argument being had again in three months.

| Option | Why it was rejected | Evidence |
| --- | --- | --- |
| The market as the landing | Named and not built: needs arrived as the pull side of the marketplace, and landing on the market settles in the shell that push wins. If the reviewer wants it, it is a small change to the work variant and a finding of its own. | — |
| | | |

## Not settled

Decisions the timebox ran out on. Each names what would settle it.

- The signed-in club directory and its anonymous twin are one screen here, with
  the visitor's data inside the signed-in chrome. Whether they are one route
  rendered twice or two routes is carried to the public-directory prototype.
- A person can be a club member, an agent and a professional at once. The
  prototype renders one role at a time and nothing on the screen says which hat
  the reader is wearing or offers to change it. That needs the account-settings
  screen, which is P2's.
- Notifications are counted as one number for a person, but the watchlist
  alarms are a club's and the mandate events are personal. Whether one badge may
  count both is open.
