Claude Skill

os-big-picture

ALWAYS invoke this skill when the user asks where the project as a whole stands - "where are we", "what's the big picture", "what have we built", "what is in this project", "map the project", "what does this thing even do", "what is stale", "what can we delete", "update the roadm

LLM Mart · 0 points · 2 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download kharmanskyi-open-steps-skills_os-big-picture-94b1cba.zip · 10 KB
Part of kharmanskyi/open-steps — 7 skills

Install

skills CLI npx skills add https://github.com/kharmanskyi/open-steps/tree/main/skills/os-big-picture
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install kharmanskyi-open-steps@llmmart
Git git clone https://github.com/kharmanskyi/open-steps.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole kharmanskyi/open-steps collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

os-big-picture

One file, BIG-PICTURE.md, where os-whats-next already looks for a backlog. It answers "where are we now" - not a plan, nothing in it a promise. Write it in the user's language; paths stay English.

When to use it. The user asks where the project stands, or there is no BIG-PICTURE.md yet → the full pass: describe, census, signals, backlog. A session report was just written → the fold-in: only the rows that session touched. Both re-measure, because a session that moves no row is the one after which the dates go quietly stale.

Step 1 - find the file, and never clobber it

BIG-PICTURE.md in the project root, and it may already be somebody's own work. Everything this skill writes lives between <!-- open-steps:begin --> and <!-- open-steps:end -->; no markers → append at the end; no file → create it, and add it to this clone's ignore list, never to .gitignore:

f=BIG-PICTURE.md; e="$(git rev-parse --git-dir)/info/exclude"
git check-ignore -q "$f" || git ls-files --error-unmatch "$f" >/dev/null 2>&1 \
  || grep -qxF "$f" "$e" 2>/dev/null || printf '%s\n' "$f" >> "$e"

Each of the three is a reason to leave it alone. Say in one line that you did it; git add -f BIG-PICTURE.md shares it instead. Never read Last worked on or Signal back out of the file - only Stage and the queue carry forward.

Step 2 - the census, measured by the script

bash "${CLAUDE_SKILL_DIR}/scripts/census.sh" .

An AGE line, then one measured PART row per part: path, last worked on, commits in six months, whether anything outside reaches it, the signal.

Step 3 - reading what it printed

Signal What it means What to do
active Being worked on Nothing
stable Quiet, and something still reaches it Leave it alone - finished and in use
unused - N months Quiet, and nothing reaches it The only real retire candidate

When the AGE line says young, write one line directly above the table, before the header row: "This project is N days old. Nothing here can be quiet for six months yet, so the Signal column will only start to mean something from the date the script gave." Every active is then a fact about the calendar, not the code. On an ok line, write no such note.

Step 4 - the backlog, sourced and never invented

Three sources, each item naming its own: session reports in ~/.claude/open-steps/reports/<project>/ (⏳ deferred rows, "Anything needed from you", recorded debt); Step 3 (each unused part, one retire candidate); the user, by hand. Nothing else - a gap you noticed while reading the code is not a task, so say it in the chat and let the user decide.

Step 5 - the tracker, if there is one

An offer, never a quiet action, and only for the "What is next" rows.

  1. Find it, never install it. gh repo view --json hasIssuesEnabled -q .hasIssuesEnabled, then any tracker already connected. Nothing connected is a normal answer: say so under "What is next", then Step 6.
  2. Search before you propose: gh issue list --search '<a few words>' --state all --json number,title,state. A closed ticket is still a match; where the search did not run, say so.
  3. Ask, then create. Plain lines through os-ask-simple; on a yes create those and nothing else, and only where this pass measured what the item rests on. Write each number back into its row, same pass.

Step 6 - plain words, before it is written

Put every sentence in the block through the os-say-simple rules first: one sentence one idea, active voice, one word for one thing. That covers the prose, the "What it does" column and the backlog items - never a measured cell.

The shape

<!-- open-steps:begin -->
_Measured <date>. Stages are dated where they stand; anything undated in this
file is not measured._

## What this is

<Three or four sentences. What the product does, who runs it, what it runs
on. No jargon - a reader who has never seen the code.>

## What is in it

| Feature | What it does | Stage | Last worked on | Signal |
|---|---|---|---|---|
| <plain name> | <one line> | live (1 Sep) | 1 Sep | active |
| <plain name> | <one line> | not checked | 28 May | stable |

## Worth retiring

<One line each: what it is, how long unused, what would break. Empty is a
result - write "nothing found" and keep the heading.>

## What is next

- <item> - <source>
- <item> - <source> - #<ticket number, once one exists>

_Age and wiring measured <date>, fresh this pass. Stage comes from session
reports and is only as current as the date beside it._
<!-- open-steps:end -->

Stage is one of building, built - not shipped, live, retired or not checked, and it carries the date it came from, always - live (12 Jul), never bare live, and not checked never dated. When the newest date in that column is months behind the newest commit, the reports have stopped: say so.

Hard rules - these rules are the skill

  1. Measured and assumed never mix. Last worked on and Signal are script output every time. Stage has no measurement.
  2. Enumerate, never guess. The parts come from the script.
  3. Quiet is not dead. No retire candidate on age alone: quiet plus wired in is stable, which is what stops the map recommending you delete a working product.
  4. Never invent work. Every backlog item names its source.
  5. Never clobber. Only between the markers. Their file stays theirs.
  6. Recommend, never act. No deleting code, moving files, opening a pull request. "Worth retiring" is a sentence, not an action.
  7. Plain words. A feature is named as the user says it, not as the folder.
  8. One screen per section. Twelve features is a wall - group and say so.
  9. A ticket only after an explicit yes. Rule 6 is the code, this is everyone else's inbox.
  10. The plain-words pass never touches a measured cell.
  11. Re-measure, never quote. A number read out of the file is a number about the past wearing today's date.
  12. Every claim carries its date or says it has none. A map that cannot go visibly stale will go invisibly stale.

Why the rules are there, the traps the script cannot catch, and a worked example: references/.

Files (open-steps)
  • references
    • 01-quiet-is-not-dead.md 3.6 KB
      # Example 1 - the map that recommended deleting a working product
      
      Synthetic. A small parcel-tracking product, two years old, one founder and two
      contractors. No confidential or third-party data.
      
      The user asked: *"What have we actually built here? Half of it feels dead."*
      
      ## What a first pass produced
      
      It listed the directories it could think of, sorted them by date, and called
      everything old a candidate for deletion.
      
      > **Stale, consider removing:** `notifier/` (7 months), `geocode/` (9 months),
      > `pdf/` (11 months), `retry/` (7 months), `csvimport/` (10 months),
      > `webhooks/` (8 months).
      >
      > Six of eleven modules are unmaintained. Recommend a cleanup sprint.
      
      Confident, tidy, and wrong in a way that costs a weekend. Every one of those
      six is imported by the running product. `geocode/` had not changed in nine
      months because it was finished - it turns an address into coordinates, and
      addresses have not changed. "Unmaintained" was never measured; it was inferred
      from a date.
      
      ## What the skill produces
      
      Two signals instead of one, and the parts enumerated from `git ls-files`
      rather than from memory.
      
      > _Measured 14 Aug. Stages are dated where they stand; anything undated in this
      > file is not measured._
      >
      > ## What this is
      >
      > A parcel-tracking service for small shops. Sellers paste a tracking number,
      > customers get a page that updates itself and an email when the parcel moves.
      > It runs as one web service with a background worker.
      >
      > ## What is in it
      >
      > | Feature | What it does | Stage | Last worked on | Signal |
      > |---|---|---|---|---|
      > | Tracking page | The page customers watch | live (12 Aug) | 12 Aug | active |
      > | Carrier polling | Asks carriers where a parcel is | live (9 Aug) | 9 Aug | active |
      > | Emails | Tells the customer it moved | live (6 Jan) | 6 Jan | stable |
      > | Address lookup | Turns an address into a map point | live (3 Nov) | 3 Nov | stable |
      > | Receipts | Makes the PDF receipt | live (21 Sep) | 21 Sep | stable |
      > | Spreadsheet import | Bulk-adds parcels from a file | not checked | 4 Dec | stable |
      > | Partner callbacks | Tells a shop's own system | live (2 Feb) | 2 Feb | stable |
      > | **Old SMS sender** | Sent texts before we moved to email | not checked | 18 Mar | **unused - 11 months** |
      >
      > ## Worth retiring
      >
      > - **Old SMS sender.** Nothing has called it since the switch to email in
      >   March, and no build or deploy script mentions it. It still holds the
      >   Twilio credentials. Removing it is about an hour.
      >
      > ## What is next
      >
      > - Finish the spreadsheet import - never confirmed working (report, 4 Dec)
      > - Decide on the old SMS sender - retire candidate above
      >
      > _Age and wiring measured 14 Aug, fresh this pass. Stage comes from session
      > reports and is only as current as the date beside it._
      
      ## What changed, and why each change is in the rules
      
      | Change | Rule |
      |---|---|
      | Six "stale" became `stable` | Each is imported by the live product. Quiet plus wired in is finished, not dead - Step 3 |
      | The real dead one appeared | `sms/` was never in the hand-written list. `git ls-files` found it - rule 2 |
      | "Recommend a cleanup sprint" became one named item | The skill recommends, it does not act - rule 6 |
      | Two rows say `not checked` | Nobody could prove those shipped. A guess would have read the same as a fact - rule 1 |
      | Both next items name a source | Neither was the agent's idea - rule 4 |
      
      The lesson that cost the most: **the retire list got shorter and became
      useful.** Six confident candidates were noise a person has to disprove one by
      one. One candidate, with the reason it is dead and the credential it still
      holds, is a decision they can make in a minute.
      
    • rationale.md 6.5 KB
      # Why the rules are there, and the traps the script cannot catch
      
      `SKILL.md` holds the rules. This file holds the reasons, and the failures each
      rule was written after. Read it when a rule looks like ceremony, or when the
      map you are about to write disagrees with one.
      
      ## Why the file exists at all
      
      Every other skill in the pack is one session wide. `os-whats-next` is told to
      read the backlog **always**, and until this skill landed nothing in the pack
      ever wrote one. The map is the standing half: the part that outlives the
      session that produced it, and the part an owner can open without an agent
      present.
      
      That is also why it is a file and not a query. A census generated on demand
      would be fresher, and useless to the person this pack is for - they would need
      an agent running to see what they own.
      
      ## Why quiet code is not dead code (rules 1 and 3)
      
      Age alone says nothing. Finished code is quiet; so is abandoned code. The two
      read identically in `git log`, which is why a map built on dates alone
      recommends deleting a working product - see
      [`01-quiet-is-not-dead.md`](01-quiet-is-not-dead.md), where six of eight
      "stale" modules were load-bearing.
      
      **`stable` is the row that protects the user.** Most quiet code is still
      imported by dozens of files. Only quiet *and* unreached is a retire candidate,
      and even then it is a sentence for the user, never an action (rule 6).
      
      ## Why nothing measured is ever read back out of the file (rule 11)
      
      A map that already exists was true on the day it was written and has been
      decaying since. `Last worked on` and `Signal` cost seconds to measure, so
      there is no case where quoting the stored value is worth being wrong. The only
      cells carried forward are the ones nothing can measure: `Stage`, and the
      queue.
      
      The same reason drives the fold-in rule. A session that fixed a bug in a
      finished feature moves no row - and it is exactly the session after which the
      dates would silently be a day older than they claim. Measuring needs no reason
      and no permission, so the fold-in measures whether or not it has news.
      
      ## Why `Stage` carries a date (rule 12)
      
      `Stage` is the one column nothing can measure. It comes from the session
      reports, from the user, or it says `not checked`.
      
      The failure this file is most likely to have is being **half fresh, and
      therefore trusted whole**: the measured columns keep refreshing themselves and
      look healthy while `Stage` quietly ages behind them. The date beside each
      stage is the cure, because it puts the decay in the row rather than in a
      footnote nobody reads. A `Stage` column that is all `not checked` is itself a
      finding - it means the reports have stopped being written, not that the
      product is unknowable. Say so.
      
      ## Why the map stays out of git
      
      The map is a working note about the project, not part of the product, and a
      `git add -A` should never sweep it into somebody's commit. So the skill puts
      it in that clone's own `.git/info/exclude`, never in the shared `.gitignore`,
      which belongs to the whole team.
      
      Three conditions stop it, and each is somebody's decision to respect: the file
      is already ignored, it is tracked because somebody chose to commit it, or the
      line is already there. **A tracked map stays tracked** - never remove it from
      git, and say once that its edits will show up in diffs.
      
      ## Why the tracker step is an offer (rule 9)
      
      A team that runs on a tracker will not read the map, so the queue has to reach
      them where they already look. But rule 6 protects the code and rule 9 protects
      everyone else's inbox: searching a tracker is free, filling one is not.
      
      - **The same item proposed twice** is how this step fails. A ticket whose
        number never made it back into its row will be offered again next session,
        and the team gets two of it.
      - **A closed ticket is still a match.** Search `--state all`. An item somebody
        already did should leave the map, not reopen as a new ticket.
      - **A stale row must never become a ticket.** A retire candidate needs the
        wiring check run today, not the one in the file. The tracker reaches people
        who never open this map, and that is exactly who a stale row would mislead.
      - **No tracker is not a fault.** Plenty of projects run on the map alone. Say
        it in one line and never turn it into a recommendation to adopt one.
      
      ## Traps the script cannot catch
      
      `scripts/census.sh` measures dates and wiring. These four it cannot see, and
      they are yours:
      
      - **A renamed folder looks new.** A whole subsystem that moved reads as three
        months old on the day it moved. `git log --follow` on a single file inside
        it when a date looks wrong.
      - **A monorepo is not one product.** Several deployables → group the map by
        deployable, or "What this is" becomes a lie of averages.
      - **git says last *touched*, not last *used*.** A part with no commits may run
        every day. That is why wiring is a separate signal and not a tiebreaker.
      - **Vendored and generated code reads as abandoned.** The script drops the
        usual folder names, but it cannot know yours. A copied-in dependency has one
        commit, years old, and is not yours to retire.
      
      ## The young repository
      
      A project younger than the quiet window has no quiet code yet - by definition,
      not by luck. Every part comes back `active`, and the map would report a
      sweeping clean bill of health it did not earn.
      
      Measured on a real five-month-old project with 1245 commits: 51 parts, all
      `active`, nothing to retire. Not one of those was a finding. So the script
      prints the repository's age, and on a young one the map says in a line above
      the table that the liveness column cannot mean anything yet, and from when it
      will. The reader then knows the column is a fact about the calendar.
      
      ## Plain words are not fewer facts (rule 10)
      
      The plain-words pass rewrites sentences, never facts. A shorter "Worth
      retiring" line that drops what would break is worse than the long one, and
      `os-say-simple`'s own hard rules carry over whole: add nothing, drop no bad
      news, numbers and dates stay exact, a claim from a report stays a claim.
      
      ## Options that were considered and rejected
      
      So a later session does not re-run the choice:
      
      | Rejected | Why |
      |---|---|
      | A hook that warns on a stale map | A threshold to tune, and it nags every session |
      | Store only the non-perishable half, generate the census on demand | Kills the reason the file exists: an owner opening it without an agent |
      | The tracker as the source of truth | No truth at all for a solo owner with no tracker |
      | Dropping `Stage` | It is the only column that says how far a feature got |
      | Keeping the map in `~/.claude` | The team could never see it |
      
  • scripts
    • census.sh 3.9 KB
      #!/usr/bin/env bash
      # The measured half of os-big-picture. Nothing here is a guess: every number
      # comes out of git. Prose, stages and the queue stay the skill's job.
      #
      #   bash scripts/census.sh [repo-path]
      #
      # It prints three kinds of line, tab separated:
      #
      #   MEASURED  <date>
      #   AGE       <days> <young|ok> <date liveness starts meaning something>
      #   PART      <path> <last worked on> <commits in the window> <wired|orphan> <signal>
      #
      # The signal is one of `active`, `stable`, `unused - N months`. It is the
      # combination of two things and never the date alone: quiet code that is still
      # reached by something is finished, not dead.
      #
      # OS_QUIET_MONTHS moves the window; the tests use it, people should not.
      set -u
      
      cd "${1:-.}" 2>/dev/null || { echo "no such directory: ${1:-.}" >&2; exit 1; }
      git rev-parse --git-dir >/dev/null 2>&1 || { echo "not a git repository" >&2; exit 1; }
      
      MONTHS="${OS_QUIET_MONTHS:-6}"
      SINCE="$MONTHS months ago"
      NOW="$(date +%s)"
      # 30-day months and a 183-day half-year, on purpose: this is a staleness
      # signal, not an anniversary. Exactness here would buy nothing.
      WINDOW=$((MONTHS * 2592000))
      
      # A copied-in dependency has one commit, years old, and is not ours to retire.
      # Build output is not a feature either. Both come off the map before anything
      # is measured, so they can never appear as a retire candidate.
      SKIP='^(node_modules|vendor|third_party|third-party|dist|build|target|\.git|\.github)$'
      
      # date(1) splits down the middle here: BSD wants -r, GNU wants -d @.
      on_day() { date -r "$1" +%Y-%m-%d 2>/dev/null || date -d "@$1" +%Y-%m-%d; }
      
      printf 'MEASURED\t%s\n' "$(on_day "$NOW")"
      
      # How old the repository itself is. A project younger than the quiet window has
      # no quiet code yet - by definition, not by luck - so the liveness column
      # cannot mean anything until it is old enough, and the map has to say so.
      BORN="$(git log --max-parents=0 --format=%ct 2>/dev/null | sort -n | head -1)"
      if [ -n "$BORN" ]; then
        DAYS=$(((NOW - BORN) / 86400))
        if [ "$((NOW - BORN))" -lt "$WINDOW" ]; then
          printf 'AGE\t%s days\tyoung\t%s\n' "$DAYS" "$(on_day "$((BORN + WINDOW))")"
        else
          printf 'AGE\t%s days\tok\t-\n' "$DAYS"
        fi
      fi
      
      # Enumerated, never typed from memory: a hand-written list of directories is
      # the most common way this skill produces a confident, wrong map.
      parts() {
        git ls-files | awk -F/ 'NF>1 {print $1}' | sort -u
        git ls-files | awk -F/ 'NF==1 {print}' | sort
      }
      
      parts | while IFS= read -r p; do
        [ -n "$p" ] || continue
        printf '%s' "$p" | grep -Eq "$SKIP" && continue
        # Repository housekeeping is not a feature: a licence, a readme, an ignore
        # file. Nothing names them, so they would read as unused on any repository
        # older than the window, and "retire .gitignore" is the confident, wrong map.
        case "$p" in
          .*|LICENSE*|LICENCE*|README*|CHANGELOG*|CONTRIBUTING*|CODE_OF_CONDUCT*|SECURITY*)
            [ -f "$p" ] && continue ;;
        esac
      
        last="$(git log -1 --format=%ad --date=short -- "$p" 2>/dev/null)"
        [ -n "$last" ] || continue
        lastct="$(git log -1 --format=%ct -- "$p" 2>/dev/null)"
        busy="$(git log --oneline --since="$SINCE" -- "$p" 2>/dev/null | grep -c . || true)"
        : "${busy:=0}"
      
        # Wiring: does anything OUTSIDE this part name it. One search covers both
        # kinds of part - code somebody imports, and a standalone thing nothing
        # imports but something builds, ships or documents. A directory is searched
        # by its name, a loose file by its name without the extension.
        name="${p%/}"
        case "$name" in */*) name="${name##*/}" ;; esac
        if [ -f "$p" ]; then base="${name%.*}"; [ -n "$base" ] && name="$base"; fi
        wired=orphan
        if [ -n "$name" ] && git grep -l -F -e "$name" -- . ":(exclude)$p" >/dev/null 2>&1; then
          wired=wired
        fi
      
        if [ "$busy" -gt 0 ]; then
          signal="active"
        elif [ "$wired" = wired ]; then
          signal="stable"
        else
          signal="unused - $(((NOW - lastct) / 2592000)) months"
        fi
      
        printf 'PART\t%s\t%s\t%s\t%s\t%s\n' "$p" "$last" "$busy" "$wired" "$signal"
      done
      
  • SKILL.md 7.2 KB
    ---
    name: os-big-picture
    description: >-
      ALWAYS invoke this skill when the user asks where the project as a whole
      stands - "where are we", "what's the big picture", "what have we built", "what is in this project", "map the
      project", "what does this thing even do", "what is stale", "what can we
      delete", "update the roadmap" - in any language, and whenever a session
      report has just been written. It keeps one file, BIG-PICTURE.md: what the
      product is, every feature with how far it got, which parts nobody has
      touched, and what is queued next. Age and wiring are measured from git; how
      far a feature got comes from the reports or says "not checked". Where a
      tracker is connected it offers to open the queue as tickets, after a yes and
      never before. Never invents work, never deletes code.
    allowed-tools:
      - "Read(~/.claude/open-steps/**)"
      - "Edit(BIG-PICTURE.md)"
      - "Bash(${CLAUDE_SKILL_DIR}/scripts/census.sh *)"
      - "Bash(git rev-parse --git-dir)"
      - "Bash(gh repo view *)"
      - "Bash(gh issue list *)"
      - "Bash(gh issue create *)"
    ---
    
    # os-big-picture
    
    One file, `BIG-PICTURE.md`, where `os-whats-next` already looks for a backlog.
    It answers "where are we now" - not a plan, nothing in it a promise. Write it
    in the user's language; paths stay English.
    
    **When to use it.** The user asks where the project stands, or there is no
    `BIG-PICTURE.md` yet → the full pass: describe, census, signals, backlog. A
    session report was just written → the fold-in: only the rows that session
    touched. Both re-measure, because a session that moves no row is the one after
    which the dates go quietly stale.
    
    ## Step 1 - find the file, and never clobber it
    
    `BIG-PICTURE.md` in the project root, and it may already be somebody's own
    work. Everything this skill writes lives between `<!-- open-steps:begin -->`
    and `<!-- open-steps:end -->`; no markers → append at the end; no file → create
    it, and add it to this clone's ignore list, never to `.gitignore`:
    
    ```bash
    f=BIG-PICTURE.md; e="$(git rev-parse --git-dir)/info/exclude"
    git check-ignore -q "$f" || git ls-files --error-unmatch "$f" >/dev/null 2>&1 \
      || grep -qxF "$f" "$e" 2>/dev/null || printf '%s\n' "$f" >> "$e"
    ```
    
    Each of the three is a reason to leave it alone. Say in one line that you did
    it; `git add -f BIG-PICTURE.md` shares it instead. Never read `Last worked on`
    or `Signal` back out of the file - only `Stage` and the queue carry forward.
    
    ## Step 2 - the census, measured by the script
    
    ```bash
    bash "${CLAUDE_SKILL_DIR}/scripts/census.sh" .
    ```
    
    An `AGE` line, then one measured `PART` row per part: path, last worked on,
    commits in six months, whether anything outside reaches it, the signal.
    
    ## Step 3 - reading what it printed
    
    | Signal | What it means | What to do |
    |---|---|---|
    | `active` | Being worked on | Nothing |
    | `stable` | Quiet, and something still reaches it | **Leave it alone** - finished and in use |
    | `unused - N months` | Quiet, and nothing reaches it | The only real retire candidate |
    
    **When the `AGE` line says `young`**, write one line directly above the table,
    before the header row: *"This project is N days old. Nothing here can be quiet
    for six months yet, so the Signal column will only start to mean something from
    the date the script gave."* Every `active` is then a fact about the
    calendar, not the code. On an `ok` line, write no such note.
    
    ## Step 4 - the backlog, sourced and never invented
    
    Three sources, each item naming its own: session reports in
    `~/.claude/open-steps/reports/<project>/` (⏳ deferred rows, "Anything needed
    from you", recorded debt); Step 3 (each `unused` part, one retire candidate);
    the user, by hand. Nothing else - a gap you noticed while reading the code is
    not a task, so say it in the chat and let the user decide.
    
    ## Step 5 - the tracker, if there is one
    
    An offer, never a quiet action, and only for the "What is next" rows.
    
    1. **Find it, never install it.** `gh repo view --json hasIssuesEnabled -q
       .hasIssuesEnabled`, then any tracker already connected. Nothing connected
       is a normal answer: say so under "What is next", then Step 6.
    2. **Search before you propose:** `gh issue list --search '<a few words>'
       --state all --json number,title,state`. A closed ticket is still a match;
       where the search did not run, say so.
    3. **Ask, then create.** Plain lines through `os-ask-simple`; on a yes create
       those and nothing else, and only where this pass measured what the item
       rests on. Write each number back into its row, same pass.
    
    ## Step 6 - plain words, before it is written
    
    Put every sentence in the block through the `os-say-simple` rules first: one
    sentence one idea, active voice, one word for one thing. That covers the prose,
    the "What it does" column and the backlog items - never a measured cell.
    
    ## The shape
    
    ```
    <!-- open-steps:begin -->
    _Measured <date>. Stages are dated where they stand; anything undated in this
    file is not measured._
    
    ## What this is
    
    <Three or four sentences. What the product does, who runs it, what it runs
    on. No jargon - a reader who has never seen the code.>
    
    ## What is in it
    
    | Feature | What it does | Stage | Last worked on | Signal |
    |---|---|---|---|---|
    | <plain name> | <one line> | live (1 Sep) | 1 Sep | active |
    | <plain name> | <one line> | not checked | 28 May | stable |
    
    ## Worth retiring
    
    <One line each: what it is, how long unused, what would break. Empty is a
    result - write "nothing found" and keep the heading.>
    
    ## What is next
    
    - <item> - <source>
    - <item> - <source> - #<ticket number, once one exists>
    
    _Age and wiring measured <date>, fresh this pass. Stage comes from session
    reports and is only as current as the date beside it._
    <!-- open-steps:end -->
    ```
    
    `Stage` is one of `building`, `built - not shipped`, `live`, `retired` or `not
    checked`, and **it carries the date it came from, always** - `live (12 Jul)`,
    never bare `live`, and `not checked` never dated. When the newest date in that
    column is months behind the newest commit, the reports have stopped: say so.
    
    ## Hard rules - these rules *are* the skill
    
    1. **Measured and assumed never mix.** `Last worked on` and `Signal` are
       script output every time. `Stage` has no measurement.
    2. **Enumerate, never guess.** The parts come from the script.
    3. **Quiet is not dead.** No retire candidate on age alone: quiet plus wired
       in is `stable`, which is what stops the map recommending you delete a
       working product.
    4. **Never invent work.** Every backlog item names its source.
    5. **Never clobber.** Only between the markers. Their file stays theirs.
    6. **Recommend, never act.** No deleting code, moving files, opening a pull
       request. "Worth retiring" is a sentence, not an action.
    7. **Plain words.** A feature is named as the user says it, not as the folder.
    8. **One screen per section.** Twelve features is a wall - group and say so.
    9. **A ticket only after an explicit yes.** Rule 6 is the code, this is
       everyone else's inbox.
    10. **The plain-words pass never touches a measured cell.**
    11. **Re-measure, never quote.** A number read out of the file is a number
        about the past wearing today's date.
    12. **Every claim carries its date or says it has none.** A map that cannot go
        visibly stale will go invisibly stale.
    
    Why the rules are there, the traps the script cannot catch, and a worked
    example: [`references/`](references/).
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related