task-new
Use to create one story in a stream of a project from the stream profile's story template - link it from its scope screens, update the generated files and open a merge request - or one projectless workspace task in tasks/.
- License 许可
- MIT
- 最近更新
- 2026-10-30
- Stars
- ★ 0
- Forks
- 0
01 前言 Front Matter
- name
- task-new
- description
- Use to create one story in a stream of a project from the stream profile's story template - link it from its scope screens, update the generated files and open a merge request - or one projectless workspace task in tasks/.
03 SKILL.md 正文
Create a story or a workspace task
Steps
- Go to the workspace root: the nearest directory, walking up from where you are, where
test -f .agents/kit.jsonsucceeds. Run every command below from there. - Ask the person which kind to create, unless they already said it:
- a story in a stream of a project: go to step 3;
- a projectless workspace task in
tasks/: go to step 21. The typesepicandstorybelong to a stream: create them only through the story flow. The task flow offerstask,bug,spike,architectureande2eonly.
Story flow
-
Collect these values:
project: the project folder name inprojects/, for exampleabs.domain: the domain folder name inprojects/<project>/domains/, for exampleoperations.stream: the stream folder name inprojects/<project>/domains/<domain>/streams/, for examplemigration.slug: the story name, lowercase letters, digits and-only ([a-z0-9-]+), for examplereports.- scope keys: one or more element keys of the form
<prefix>:<project>/<domain>/<slug>, for examplescreen:abs/operations/reports. Or, when the story covers no element (for example BFF defects), no keys and a one-line unmapped reason. The reason must not contain|and must not start with[,{,"or'. wave: a number, for example2.- depends: story keys this story waits for, for example
story:abs/operations/login, or none. - repos: repository keys, for example
repo:reports-bff, or none. title: the story title for the#title line of the story template, for exampleReports. Only needed when the template has such a line (step 6 chooses the template), for example# [СО] <Название стори>instory.ru.md.
Use every value the person gave. Derive the others from the files by the rules below, and do not ask the person to confirm a derived value: the person corrects derived values in the merge request review. Ask the person only for a value that is neither given nor derivable, and wait for the answer. Never invent a value.
- Stream. When the person named the project, the domain and the stream, use them. Otherwise run
ls projects/*/domains/*/streams/*/stream.json; each printed pathprojects/<project>/domains/<domain>/streams/<stream>/stream.jsonis one stream. Keep the streams whose project folder, domain folder, stream folder orkeyinstream.jsonthe request names. When the request names no stream, keep instead the streams that have an uncovered scope key (see Scope). When exactly one stream is left, take its<project>,<domain>and<stream>. When several or none are left, ask the person for the project, the domain and the stream. - Scope. When the person named element keys, use them. When the request asks for the element or elements that have no story yet, read the
scopelist ofprojects/<project>/domains/<domain>/streams/<stream>/stream.jsonand, for each key in it, rungrep -lxF -e ' - <key>' projects/<project>/domains/<domain>/streams/<stream>/stories/*/story.md 2>/dev/null. The key is uncovered when the command prints no path. The scope keys are the uncovered keys, in the order of thescopelist. When no key is uncovered, stop, tell the person every scope key of the stream has a story, and change nothing. When the request asks for a story that covers no element, ask the person for the unmapped reason. wave. For each scope key, open its element file (step 9 gives the path) and read itswave:line. Take the lowest number. Without scope keys, ask the person.slug. When the scope has exactly one key, take the text after the last/in that key, for examplecardforscreen:abs/demo/card; step 8 checks that it is free. Otherwise ask the person.- depends and repos: none, unless the person named them.
title. When the person gave a title, use it. Otherwise, when the scope has exactly one key, take thelabel:value of its element file (step 9 gives the path). Otherwise (several keys, no keys, or an emptylabel:) ask the person for the title. Never invent a title.type,tracker,decisionsandmockupsare not asked: step 13 keepstype,decisionsandmockupsfrom the template, keepsstatus,ownerandstartedas the template has them, andtrackerstays empty unless step 6 needs one.
-
Check the slug: run
printf '%s\n' '<slug>' | grep -Ex '[a-z0-9-]+'. When it prints nothing, ask the person for another slug. -
Find the workspace default branch: run
git symbolic-ref --short refs/remotes/origin/HEADand remove theorigin/prefix; when the command fails, usemain. Call it<default>. Then run, one by one:git switch <default>GIT_TERMINAL_PROMPT=0 git pull --ff-onlyThe checks in steps 6 to 10 run after the pull, so they see the fresh default branch.
-
Run
test -f projects/<project>/domains/<domain>/streams/<stream>/stream.json. When it fails, stop, tell the person the stream does not exist, and change nothing. Otherwise read the file and takeprofile,stageand thescopelist.- Find the workspace language
<language>: open.agents/kit.jsonand readparams.language. When the file,paramsorlanguageis missing,<language>isen. - Find the story template
<template>: when<language>is notenandtest -f .agents/profiles/<profile>/story.<language>.mdsucceeds, it is.agents/profiles/<profile>/story.<language>.md; otherwise.agents/profiles/<profile>/story.md. For languageruin profileui-migrationit isstory.ru.md. - Values in
.agents/profiles/<profile>/profile.jsonmay be language objects such as{"en": "Open questions", "ru": "Открытые вопросы"}. Wherever this skill reads a value fromprofile.json, take the<language>value of such an object, or itsenvalue when it has no<language>key. - Find the open questions section
<open questions>: thesectionof the gate"gate": "no_open_questions"instagesofprofile.json, for exampleOpen questions(en) orОткрытые вопросы(ru). When no such gate exists, there is no open questions section. - When
stageisgoal,map,decompositionorready: the story gets no tracker id. Go to step 7. - When
stageisdeliveryordone: thereadystage is closed, so itstracker_idsgate requires a tracker id for the new story too. Ask the person for the tracker id<tracker>and wait for the answer. When the person gives none, stop, tell them a stream at stage<stage>needs a tracker id for every story, and change nothing. Do not create any file or branch. - Check
<tracker>: readtracker/trackers.json. Every entry oftrackerscarrieskeyandid_pattern; JSON doubles every backslash, so\\din the file means\d. Rewrite each pattern forgrep -E(write every\das[0-9]) and runprintf '%s\n' '<tracker>' | grep -Ex '<rewritten pattern>'entry by entry until one matches. When no entry matches, ask the person for another id. Whentracker/trackers.jsonhas notrackerslist, or no entry has anid_pattern, stop, tell the person, and change nothing. - When
<tracker>contains a"or a\character, ask the person for another id:.agents/index.jsonstores such ids escaped, so the next check cannot find them. - Run
grep -F ' "<tracker>":' .agents/index.json 2>/dev/null. When it prints a line, the id belongs to another task: ask the person for another id.
- Find the workspace language
-
For each scope key from step 3, check that it is one of the strings in the
scopelist ofstream.json, exactly. When a key is not in that list, stop, tell the person which key is outside the stream scope, and change nothing. Do not create any file or branch.- When step 3 found the scope keys as uncovered keys, run its
grepagain for each of them. When it now prints a path, that story covers the key since the pull: stop, tell the person the path, and change nothing.
- When step 3 found the scope keys as uncovered keys, run its
-
Run
ls -d projects/<project>/domains/<domain>/streams/*/stories/<slug>. When it prints a path, the slug already exists: stop, tell the person the path, and change nothing. When step 3 derived the slug, ask the person for another slug and continue from step 4 with the answer. -
For each scope key, find its element file:
- The key has the form
<prefix>:<element project>/<element domain>/<element slug>. Open.agents/profiles/<profile>/profile.jsonand find the entry ofelementswhoseprefixequals<prefix>. Itsdirgives the pathprojects/<element project>/domains/<element domain>/<dir>/<element slug>.md. Forscreen:abs/operations/reportsin profileui-migrationit isprojects/abs/domains/operations/map/reports.md. - Run
test -f <path>. When it fails, stop, tell the person the element file is missing, and change nothing.
- The key has the form
-
Check depends and repos:
- For each depends key
story:<d>/<dd>/<s>, runls projects/<d>/domains/<dd>/streams/*/stories/<s>/story.md 2>/dev/null. It must print exactly one path. - For each repos key
repo:<name>, rungrep -F '"name": "<name>"' repos.json. It must print a line. - Correct or drop, together with the person, every key that fails. Never keep a key that does not exist.
- For each depends key
-
Run
git switch -c story-<domain>-<slug>. -
Run
mkdir -p projects/<project>/domains/<domain>/streams/<stream>/stories/<slug> && cp <template> projects/<project>/domains/<domain>/streams/<stream>/stories/<slug>/story.md. -
Edit the frontmatter of the new
story.md. Keep every line of the template in its order and change only these lines:key: story:<project>/<domain>/<slug>;- keep
status: waitingand the emptyowner:andstarted:lines exactly as the template has them: a new story waits, unowned and not started -task-startwrites those three lines later; wave: <wave>;scope: with keys, the linescope:followed by one line- <key>per key (two spaces,-, space), in the order of step 3; without keys, the linescope: []and directly below it the lineunmapped: <reason>. Theunmapped:line is the only line the template does not have; write it only when the scope is empty;dependsandrepos: the same form,<field>:followed by- <key>lines, or<field>: []when empty;tracker: when step 6 gave a<tracker>,tracker: <tracker>; otherwise leavetracker:empty;- leave
type,decisionsandmockupsas the template has them. Keep every##heading of the template and replace the placeholder text under each of them. The sections are those of<template>, in their order; their names are thestory.sectionslist ofprofile.json. When the template has a#title line, replace its placeholder in angle brackets with<title>from step 3 and keep the rest of the line:# [СО] <Название стори>becomes# [СО] Отчётыfor titleОтчёты. Where the person gave you the words for a section, write those words. Otherwise write: - the summary section: the section named by
story.summary_sectionofprofile.json(in<language>as step 6 says), or the first item ofstory.sectionswhensummary_sectionis absent. It gets the goal. With scope keys, one lineDeliver <key> (<label>, <route>)., listing every scope key as<key> (<label>, <route>)joined with,; without keys, the line<reason>.; - the section whose template text names the covered screens (it mentions
screen:keys or thescopefield): with scope keys, one line<key>: <label>, <route>per key; without keys, the lineUnmapped: <reason>; ## <open questions>:None.;- every other section: the one line
Written in the merge request review.. Take<label>and<route>from thelabel:androute:lines of the element file from step 9. When the element file has no such line or it is empty, leave that part out, for example<key>alone. Forscreen:abs/demo/cardwith labelCardand route/card, the screens section getsscreen:abs/demo/card: Card, /card. Whenstageisdeliveryordone, the text under## <open questions>must beNone.or nothing: keepNone.and write no questions there, and tell the person in the report to resolve open questions before merging.
Sections without text from the person, for scope
screen:abs/demo/cardwith labelCardand route/card:English ( story.md)Russian ( story.ru.md)Text no title line # [СО] <Название стори>the title: # [СО] Card## Goal(summary section)## Цель(summary section)Deliver screen:abs/demo/card (Card, /card).## Scope## Функциональные требованияscreen:abs/demo/card: Card, /card## Acceptance criteria,## Verification,## Out of scope## Заинтересованные стороны,## Описание бизнес-потребности,## Нефункциональные требования,## Задачи внутри стори,## ЭтапыWritten in the merge request review.## Open questions## Открытые вопросыNone.Example with a scope:
--- key: story:abs/operations/reports type: story status: waiting owner: started: wave: 2 tracker: scope: - screen:abs/operations/reports depends: - story:abs/operations/login repos: [] decisions: [] mockups: [] ---Example without a scope:
--- key: story:abs/operations/bff-defects type: story status: waiting owner: started: wave: 3 tracker: scope: [] unmapped: BFF returns wrong totals, no screen changes depends: [] repos: - repo:reports-bff decisions: [] mockups: [] --- -
Link the scope elements. For each element file from step 9, find its frontmatter line
story:.- When the line is exactly
story:(empty), change it tostory: story:<project>/<domain>/<slug>. - When the line already names a story, leave it unchanged and tell the person in the report.
- Change nothing else in the element file. Remember the element files you changed.
- When the line is exactly
-
Update the generated files. If
command -v python3prints a path, runpython3 tools/generate.py. It rewrites the stream'sBREAKDOWN.md, the story cells of the domainMAP.mdfiles,.agents/index.jsonandSTATUS.md. Otherwise do all three:-
apply
## Recipe: BREAKDOWN.md row; -
apply
## Recipe: index entry; -
for each element file you changed in step 14, change one cell in
projects/<element project>/domains/<element domain>/MAP.md. Find the begin marker of the element kind (<!-- map:screens:begin -->forscreen) and its end marker. WhenMAP.mdor the marker pair is absent, skip this element. Between the markers, the first line is the header, for example| key | route | kind | section | parent | access | label | wave | story |; count which column isstory. Find the row that starts with| <element key> |. In that row, replace only the text of thestorycell: the empty cell| |(two spaces between the bars) becomes| story:<project>/<domain>/<slug> |. Change nothing else. When there is no such row, do not add one; tell the person the table is stale and needspython3 tools/generate.py.Row before, in
projects/abs/domains/operations/MAP.md:| screen:abs/operations/reports | /reports | place | Reports | | reports.read | Reports | 2 | |Row after creating
story:abs/operations/reports:| screen:abs/operations/reports | /reports | place | Reports | | reports.read | Reports | 2 | story:abs/operations/reports |
-
-
Run the check. First run
command -v python3.- When it prints a path (Python is present): run
python3 tools/check.pyat most three times in total. After each run, look only at findings that name a file this skill changed: the newstory.md, the element files from step 14,projects/<element project>/domains/<element domain>/MAP.md,projects/<project>/domains/<domain>/streams/<stream>/BREAKDOWN.md,.agents/index.jsonandSTATUS.md.- Fix such a finding only when the fix needs no new value, for example a wrong line format, order or comma, or a stale generated file (run
python3 tools/generate.py). Then run the check again. - When such a finding needs a value only the person has (for example a tracker id, a scope key, or answers to open questions), do not fix it and do not invent the value. Stop: do not commit, list these findings for the person, and wait.
- When no finding names these files, go on to step 17.
- When the third run still has findings in these files, stop: do not commit, list the findings for the person, and wait.
- Findings in other files: do not fix them; list them in the report.
- Fix such a finding only when the fix needs no new value, for example a wrong line format, order or comma, or a stale generated file (run
- When it prints nothing (Python is missing): do not run the check. Remember the line
check not run: python3 missingfor the report.
- When it prints a path (Python is present): run
-
Commit: run
git status --short --untracked-files=allin the workspace.- Stage every path whose status is not
??: rungit addfor each of them. - Stage every
??path this skill created: the new story folderprojects/<project>/domains/<domain>/streams/<stream>/stories/<slug>/, andprojects/<project>/domains/<domain>/streams/<stream>/BREAKDOWN.mdwhen## Recipe: BREAKDOWN.md rowcreated it because it did not exist yet. - Stage every other
??path that is a generated file: its path starts with.claude/,.opencode/or.cursor/, or it is exactlyCLAUDE.md,.agents/index.json,REPOSITORIES.mdorSTATUS.md, or it matchesprojects/*/domains/*/streams/*/BREAKDOWN.md. - Do not stage any other
??path; mention it in the report to the person. - Run
git commit -m "docs(story): add <project>/<domain>/<slug>".
- Stage every path whose status is not
-
Run
GIT_TERMINAL_PROMPT=0 git pull --rebase origin <default>. On conflicts follow## Conflicts. After the rebase has finished, run step 16 again. When step 16 stops, do not amend and do not push; wait for the person. When it made you fix a file, rungit add <file>for each fixed file, thengit commit --amend --no-edit. -
Push and open the merge request by
.agents/rules/merge-requests.md, with branchstory-<domain>-<slug>and titleAdd story <project>/<domain>/<slug>. UseGIT_TERMINAL_PROMPT=0beforegit push. -
Report to the person:
- the story file
projects/<project>/domains/<domain>/streams/<stream>/stories/<slug>/story.md, and its tracker id when step 6 gave one; - the values step 3 derived, and that the person corrects them and writes the section text in the merge request review;
- the element files whose
storyyou set, and the ones you left because they already named a story; - the branch
story-<domain>-<slug>; - the merge request link, or the instruction to open it;
- the remaining check findings in other files, when there are any;
- as the last line, the check result, or
check not run: python3 missing.
- the story file
Workspace task flow
- Collect these values:
slug: the task name, lowercase letters, digits and-only ([a-z0-9-]+), for examplebilling-architecture. It is the last part of the keytask:<slug>.type: ask the person to choose one oftask,bug,spike,architecture,e2e. When they nameepicorstory, tell them these types live in a stream and offer the story flow (step 3) instead.tracker: optional. When the person gives none, thetracker:line stays empty. When they give one, check it the way step 6 does: pattern entry by entry, then the"and\rule, then the duplicate check in.agents/index.json. Every failed check asks the person for another id or for none.- a one-line summary for the title, for example
Split billing into two services.
- Check the slug:
printf '%s\n' '<slug>' | grep -Ex '[a-z0-9-]+'must print the slug, andtest -e tasks/<slug>must fail. When the folder already exists, stop, tell the persontasks/<slug>/already exists, and change nothing. When the slug has another form, ask for another slug. - Find the workspace default branch as step 5 does, then run
git switch <default>andGIT_TERMINAL_PROMPT=0 git pull --ff-only. - Run
git switch -c task-<slug>. - Run
mkdir -p tasks/<slug> && cp .agents/templates/task.md tasks/<slug>/task.md. - Edit the new
task.md. Keep every line of the template in its order and change only these lines:key: task:<slug>;type: <type>from step 21;- keep
status: waitingand the emptyowner:andstarted:lines exactly as the template has them: a new task waits, unowned and not started -task-startwrites those three lines later; tracker: <tracker>when step 21 gave one; otherwise leavetracker:empty. Replace the title line# <slug>: <one-line summary>with the slug and the summary of step 21. Keep every##heading. Where the person gave you the words for a section, write those words under it; otherwise keep the template text under that heading and say in the report that the person fills the sections before starting the task.
- Update the generated files. If
command -v python3prints a path, runpython3 tools/generate.py. It rewrites.agents/index.json(thetask:<slug>entry, and the tracker alias when one was set) andSTATUS.md(the row in theworkspacegroup of the waiting section). Otherwise apply## Recipe: index entryfortask:<slug>. - Run the check as step 16 does, at most three times in total, looking only at findings that name
tasks/<slug>/task.md,.agents/index.jsonorSTATUS.md, with the same fix, stop and report rules. - Commit as step 17 does, with these differences: the created folder is
tasks/<slug>/; noBREAKDOWN.mdis created; the commit message isgit commit -m "docs(task): add <slug>". - Run
GIT_TERMINAL_PROMPT=0 git pull --rebase origin <default>. On conflicts follow## Conflicts. After the rebase has finished, run step 28 again. When step 28 stops, do not amend and do not push; wait for the person. When it made you fix a file, rungit add <file>for each fixed file, thengit commit --amend --no-edit. - Push and open the merge request by
.agents/rules/merge-requests.md, with branchtask-<slug>and titleAdd task <slug>. UseGIT_TERMINAL_PROMPT=0beforegit push. - Report to the person:
- the task file
tasks/<slug>/task.md, and its tracker id when step 21 gave one; - that the person fills the sections that still carry the template text before starting the task;
- the branch
task-<slug>; - the merge request link, or the instruction to open it;
- the remaining check findings in other files, when there are any;
- as the last line, the check result, or
check not run: python3 missing.
- the task file
Recipe: BREAKDOWN.md row
Use this only when python3 is missing. The result equals what python3 tools/generate.py writes.
-
Build the row from the frontmatter of the new
story.md, copying values verbatim (without surrounding quotes):| story:<project>/<domain>/<slug> | <wave> | <scope joined with ", "> | <unmapped> | <tracker> | <depends joined with ", "> |An empty value leaves an empty cell with two spaces between the bars:
| |. For example scope[]with unmappedBFF defectsand no tracker and no depends gives| story:abs/operations/bff-defects | 3 | | BFF defects | | |. -
Open
projects/<project>/domains/<domain>/streams/<stream>/BREAKDOWN.md. When it does not exist, create it with exactly these six lines, each ending with a newline:# <title> stream:<project>/<domain>/<stream> <note> | <column 1> | <column 2> | <column 3> | <column 4> | <column 5> | <column 6> | |---|---|---|---|---|---|Take
<title>,<note>and the six columns from thebreakdownblock of.agents/profiles/<profile>/profile.json(title,noteandcolumnsin their order), in<language>as step 6 says. Whenprofile.jsonhas nobreakdownblock, use titleBreakdown of, noteGenerated by tools/generate.py from stories/*/story.md. Do not edit.and columnsStory,Wave,Scope,Unmapped,Tracker,Depends. The row cells keep the order of step 1 whatever the column names are.English (
en, and every profile without abreakdownblock):# Breakdown of stream:demo/operations/migration Generated by tools/generate.py from stories/*/story.md. Do not edit. | Story | Wave | Scope | Unmapped | Tracker | Depends | |---|---|---|---|---|---|Russian (
ru, profileui-migration):# Разбивка stream:demo/operations/migration Сгенерировано tools/generate.py из stories/*/story.md. Не редактировать. | Стори | Волна | Экраны | Без экрана | Трекер | Зависит от | |---|---|---|---|---|---|(The blank lines count: the file starts with the title line, a blank line, the note line, a blank line, the header line and the separator line.)
-
Rows follow the separator line in ascending slug order. Compare your slug with the slug of each row (the text after the last
/in its first cell) character by character from the left; the first different character decides in this order:-, then digits0to9, then lettersatoz. When one slug is the start of the other, the shorter one comes first. Sologin<reports<reports-v2<reports2. -
Insert your row directly above the first row whose slug comes after yours. When no row comes after yours, add it as the last line of the file. Change nothing else. The file ends with a newline.
Example. BREAKDOWN.md before:
# Breakdown of stream:demo/operations/migration
Generated by tools/generate.py from stories/*/story.md. Do not edit.
| Story | Wave | Scope | Unmapped | Tracker | Depends |
|---|---|---|---|---|---|
| story:demo/operations/login | 1 | screen:demo/operations/login | | DEMO-101 | |
| story:demo/operations/users | 2 | screen:demo/operations/users, screen:demo/operations/user-view | | | story:demo/operations/login |
After creating story:demo/operations/reports with wave 2, scope screen:demo/operations/reports, depends story:demo/operations/login:
# Breakdown of stream:demo/operations/migration
Generated by tools/generate.py from stories/*/story.md. Do not edit.
| Story | Wave | Scope | Unmapped | Tracker | Depends |
|---|---|---|---|---|---|
| story:demo/operations/login | 1 | screen:demo/operations/login | | DEMO-101 | |
| story:demo/operations/reports | 2 | screen:demo/operations/reports | | | story:demo/operations/login |
| story:demo/operations/users | 2 | screen:demo/operations/users, screen:demo/operations/user-view | | | story:demo/operations/login |
Recipe: index entry
Use this only when python3 is missing. The result equals what python3 tools/generate.py writes.
.agents/index.json is one JSON object with one entry per line, two spaces of indentation, in this order: adr: entries, then diagram: and mockup: entries, then the story: and task: entries ascending by key - every story: entry comes before every task: entry -, then tracker ids ascending by id. A tracker id entry maps the task's tracker value to the same task file path.
Ascending means: compare two keys character by character from the left; the first different character decides in this order: -, ., /, digits 0 to 9, :, upper-case letters A to Z, _, lower-case letters a to z. When one key is the start of the other, the shorter one comes first. So story:demo/operations/login < story:demo/operations/reports, story:demo-new/a < story:demo/a, and DEMO-145 < DEMO-99 (not number order).
- Build your entry line. A story:
"story:<project>/<domain>/<slug>": "projects/<project>/domains/<domain>/streams/<stream>/stories/<slug>/story.md". A workspace task:"task:<slug>": "tasks/<slug>/task.md". - Find its position among the lines starting with
"story:or"task::- When the file has such lines, insert your line directly above the first of them whose key comes after yours. When none comes after yours, insert it directly after the last of them.
- When there is no
"story:or"task:line, insert it directly after the last line starting with"adr:,"diagram:or"mockup:. - When there is none of those either, insert it as the first entry, directly after the line
{. - When the whole file is the single line
{}, replace that line with three lines:{, your line,}.
- Only when the task's
trackeris not empty (step 6 sets it for a stream at stagedeliveryordone, step 21 whenever the person gives one): build the line"<tracker>": "<task file path>"with the same path as your entry line, writing"as\"and\as\\inside the id. Tracker lines are the entry lines after the last"story:or"task:line. When a line with the same id already exists, add nothing and tell the person the id is used by another task. Otherwise insert your line directly above the first tracker line whose id comes after yours; when none comes after yours, insert it as the last entry, directly above the line}. - Commas: every entry line ends with
,except the last entry, directly above}. After inserting, add the missing,to the line above your line, and end your line with,unless it is the last entry. - Keep no trailing spaces. The file ends with
}and a newline. Change nothing else.
Example 1. The index is {}. After creating story:demo/operations/reports in stream migration:
{
"story:demo/operations/reports": "projects/demo/domains/operations/streams/migration/stories/reports/story.md"
}
Example 2. Before:
{
"adr:0001": "docs/adr/0001-use-kafka.md",
"mockup:demo/operations/login": "https://design.example.org/file/login",
"story:demo/operations/login": "projects/demo/domains/operations/streams/migration/stories/login/story.md",
"story:demo/operations/users": "projects/demo/domains/operations/streams/migration/stories/users/story.md",
"task:billing-architecture": "tasks/billing-architecture/task.md",
"DEMO-101": "projects/demo/domains/operations/streams/migration/stories/login/story.md"
}
After creating story:demo/operations/reports in stream migration:
{
"adr:0001": "docs/adr/0001-use-kafka.md",
"mockup:demo/operations/login": "https://design.example.org/file/login",
"story:demo/operations/login": "projects/demo/domains/operations/streams/migration/stories/login/story.md",
"story:demo/operations/reports": "projects/demo/domains/operations/streams/migration/stories/reports/story.md",
"story:demo/operations/users": "projects/demo/domains/operations/streams/migration/stories/users/story.md",
"task:billing-architecture": "tasks/billing-architecture/task.md",
"DEMO-101": "projects/demo/domains/operations/streams/migration/stories/login/story.md"
}
Conflicts
For this skill a conflicted file counts as generated when it is .agents/index.json, STATUS.md, a stream BREAKDOWN.md, or a MAP.md whose conflicts all lie between map: markers (see step 2). Every other file, including story.md, task.md, element files and stream.json, is not generated.
- List all conflicted files:
git diff --name-only --diff-filter=U. Write the list down before you change anything. - For each
MAP.mdin the list, rungrep -n -e '^<<<<<<<' -e '^>>>>>>>' -e '<!-- map:' <file>. The file counts as generated only when every<<<<<<<line and the>>>>>>>line after it both lie between one:begin -->line and the next:end -->line. Otherwise it is not generated. - First check the whole list for any file that is not generated. If there is one:
- Run
git rebase --abort. Do not touch any file first, not even the generated ones. - For each file that is not generated, show the person both versions with these labels:
- "default branch": the output of
git show origin/<default>:<file>; - "your branch": the output of
git show <branch>:<file>, where<branch>isstory-<domain>-<slug>in the story flow andtask-<slug>in the task flow. When one of the two commands fails, tell the person that side has no such file.
- "default branch": the output of
- Stop and wait for the person.
- Run
- Only when every file in the list is generated:
- For each file in the list, run
git checkout --ours -- <file>. During a rebase--oursis the default branch version, so your own change in that file is gone. - Regenerate: if
command -v python3prints a path, runpython3 tools/generate.py. Otherwise apply again, to the files in the list, what step 15 does for a story (## Recipe: BREAKDOWN.md row,## Recipe: index entry, thestorycell change inMAP.md) and step 27 for a task (## Recipe: index entry). - For each file in the list, run
git add <file>. Alsogit addany other generated file the regeneration changed. - Run
GIT_EDITOR=true git rebase --continue. When it stops on conflicts again, go back to step 1.
- For each file in the list, run
Without Python
- Skip
python3 tools/generate.pyandpython3 tools/check.pyeverywhere, including## Conflicts. Instead apply, at step 15 for a story and at step 27 for a task, the recipes named there. STATUS.mdis generated, and this kit version ships no hand recipe for adding a waiting row yet. After step 15 or step 27, do not commit and do not push: tell the person to runpython3 tools/generate.py, and continue from step 17 or step 29 after they have.- End the report with the line:
check not run: python3 missing
04 同仓库更多 Skills
verify
Use when a change in __SERVICE__ must be checked before review
work-record
Use when you finished work on a tracker task and it must be recorded in the workspace through a merge request.
task-new
Use to create one story in a stream from the stream profile's story template, link it from its scope screens and open a merge request.
task-decompose
Use to split a stream at the decomposition stage into stories - list scope screens without a story, create the accepted stories and close the stage through a merge request.
task-context
Use to gather the context of a story key or a tracker id - its story, stream stage, scope screens, repositories, decisions, mockups and work records.
repos-sync
Use to update clones of your repositories under repos/ and see their branch, lag and uncommitted changes.