feat: fix the Project Profile home to one Asana task per project - #61
Merged
Merged
Conversation
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
The profile's canonical home was an open decision, so onboarding asked the PM where to put it and every consumer asked where to find it. Nobody recorded the answer anywhere durable, so a later run could not locate a profile that already existed — and skills did not stop when they could not find one. estimation ran without profile-driven widening; recipes and ui-creation fell back to house defaults and ignored overrides that existed. Both looked like successful runs. The profile now lives in Asana as `Project Profile - <project name>` in the project it describes, one subtask per section. The convention is fixed in raftkit-core/workflow-constants, so every consumer resolves it the same way and none of them ask. - core: the convention, plus how to find a project's profile (read all subtasks; never look one up by section name, since a thin profile has fewer sections) - pm: onboarding writes the parent + subtasks, takes the Asana project as an input and never infers it from a source's contents, resolves a rough project name against Asana, re-targets without re-ingesting when the PM corrects it, and treats a write timeout as possibly-succeeded rather than blind-retrying - pm/qa/dev: estimation, meeting-decisions, story-skill-generator, user-story, brainstorm, test-suite, recipes, ui-creation and docs all resolve by convention instead of asking - facts render as lists, never tables — Asana renders no table in a task description; the draft is shown in the shape it will be written Verified end to end against a scratch Asana project: parent, five subtasks, no tables, conflicts as nested lists, read-back clean. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Asana keeps no history of a description edit — an overwritten subtask leaves no trace of what it said before, and the task's story feed stays silent. Verified on a live delta: five subtasks were rewritten and Asana logged nothing at all, so the only record was the terminal scrollback the PM had already approved. Onboarding and meeting-decisions now post one comment on the parent task after a delta's writes land: source added, subtasks rewritten, then changed / new / conflicts added / now-confirmed. One comment per run, never one per subtask. It records what changed rather than the new content, so it grows with the size of the change and not the size of the profile. That makes it an audit trail, not a backup — restoring an earlier value still means going back to its source. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ofile The wording said "the Project Profile and/or the project's own sources", which let a run ground entirely in other sources and never mention that a profile existed. Observed on a live run: it read workflow-constants to learn how profiles are found, then listed five repo files as its sources and never fetched the profile task that was sitting in the project. That is the same silent omission this branch removed from estimation — a profile is there, it is not used, and nothing says so. Using the profile is now the default, and not using it is a stated decision with a reason. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Rebased onto development, which had landed PR #60 implementing the other answer to the same decision — a Drive doc plus a pinned Asana resource task. The eight overlapping files now carry the Asana-task home; PR #60's contract suite is kept and re-aimed rather than replaced, since its shape was right and only its assertions pointed the other way. Also kept from #60: the `Profile lives at:` completion line, which does the same job as this branch's `Profile:` line and reads better. 26 checks, mutation-verified — inverting the no-override rule and the read-all-subtasks rule each turn a check red. Adds coverage #60 did not have: core owning the convention, the project never being inferred from a source, the exact no-project stop message, and the delta record. Versions bumped above development: core 0.17.0, pm 0.25.0, qa 0.11.0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ravi-solanki-31
force-pushed
the
feat/project-profile-asana-home
branch
from
August 21, 2026 10:10
c6061d7 to
305cd9d
Compare
Its description carried "amend mode: a diff-first additive edit". A colon followed by a space ends a plain YAML scalar, so the whole frontmatter failed to parse and the skill loaded with empty metadata — name, description and the user-invocable flag all silently dropped. Pre-existing on development; it surfaces here because CI validates the skills a PR touches. Colon swapped for a dash. Scanned every other SKILL.md in the marketplace — no other frontmatter fails to parse. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Resolving the manifest conflicts left raftkit-pm with two "description" keys — development's, naming the deprecation sweep, and this branch's older one. JSON takes the last, so the stale description won and drifted from marketplace.json. All three manifests are now development's file verbatim with only the version line changed, which is the only thing this branch should be touching in them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Review feedback on the generated profile: too much information packed into each subtask, and subtask names that do not say what is inside them. Both are fair — the test run put ~45 facts into "Business rules and limits" under seven internal headings, several single facts ran past 80 words, and the tag legend was repeated at the top of all five subtasks. Four rules, so a profile is written to be read: - A fact is one sentence, inside the house 25-word limit. A fact needing three clauses is three facts, each carrying its own tag — an 80-word bullet hides which part is confirmed and which is not. - One subject per section. The four named sections are a starting point, not a ceiling: past about 15 facts a section splits by subject, and headings appearing inside a section mean those headings were the sections. - Subtask names carry a plain-English gloss — "Glossary — what the project's terms mean" — so someone opening a profile cold knows what is in it. - Each subtask opens with one line saying what it holds and how many facts. The tag legend sits on the parent once instead of five times. 7 new contract checks, mutation-verified. pm 0.26.0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The regenerated profile came back with four subtasks called "Architecture & delivery loop" and the like. The escape rule said to escape &, < and > in text content without saying where it applies, so it was applied to task names as well as HTML bodies. A name is plain text on the way in, so nothing decodes it and the reader sees the entity. Rule now says escaping is for an HTML body only. The four subtasks in the test profile were renamed by hand. 1 contract check, mutation-verified. core 0.18.0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Story
None. This implements
Decision · Project Profile canonical home(Asana1216550765662503). No board story was written for it, so there are no[AC]s to check against andscope-guardcould not run — it audits a diff against a story's[AC]s and Out-of-scope section. Flagging that rather than claiming a gate that did not happen. The contract suite below covers what[AC]s would have.Supersedes PR #60
The decided home is one Asana task per project with a subtask per section. PR #60 is already merged into
developmentand implements the earlier proposal for the same decision — a Google Drive doc plus a pinned Asana resource task linking it — so this branch is rebased on top of it and replaces that wording. Drive stays a source, never a destination.What was kept from #60 rather than discarded:
tests/profile-home.test.sh). The shape was right and only the assertions pointed at the other home, so it is re-aimed rather than replaced — now 26 checks, mutation-verified.Profile lives at:completion line, which does the same job as this branch'sProfile:line and reads better.estimationinto a feature-list skill is preserved intact; only its profile-home sentence changed.Story
1217123036545807, which #60 shipped against, still describes the Drive-doc home and needs correcting so the board and the code agree.What changed
The profile's canonical home was an open decision, so
project-onboardingasked the PM where to put it and every consumer asked where to find it. Nobody recorded the answer anywhere durable, so a later run could not locate a profile that already existed — and the consumers did not stop when they could not find one:estimationran without profile-driven widening and emitted a confident rangerecipesandui-creationfell back to house defaults, ignoring overrides that existedtest-suitetold QA to build a profile that was already thereAll of it looked like a successful run.
The profile now lives in Asana as
Project Profile - <project name>in the project it describes, one subtask per section. The convention is fixed inraftkit-core/workflow-constants, so every consumer resolves it the same way and none of them ask. There is no per-project override — a home that varies is a home nobody can be sure of.Also in here:
user-storystates when it is not grounding a story in the profile, instead of omitting it silently.user-story's frontmatter parses again. Its description containedamend mode: a diff-first…, and a colon-space ends a plain YAML scalar, so the skill was loading with all frontmatter dropped. Pre-existing ondevelopment; it surfaced here because CI validates the files a PR touches. Every other SKILL.md was scanned — no others affected.Readability pass (review feedback)
The first version was correct but hard to read: the test run put ~45 facts into "Business rules and limits" under seven internal headings, single facts ran past 80 words, and the tag legend was repeated at the top of all five subtasks. Four rules now govern how a profile is laid out.
GlossaryGlossary — what the project's terms meanSame facts and citations, laid out to be read.
Regenerating the test profile under these rules turned 5 subtasks into 20, each on one subject, each named so it explains itself —
Third-party dependencies: core tooling — required for every dev. It also surfaced one bug, fixed here: task names were being HTML-escaped, so four came out asArchitecture &amp; delivery loop. Escaping belongs to an HTML body; a name is plain text.8 further contract checks cover all of it.
Verified
tests/profile-home.test.sh— 34 checks, all green, mutation-verified (inverting the no-override rule or the read-all-subtasks rule each turns a check red). Covers the decided home, the never-infer rule, the exact no-project stop message, the completion line, all eight consumers, core owning the convention, the delta record, and the version floors.Behaviourally, against a live scratch Asana project with plugins loaded from this branch:
story-skill-generator(pm) andtest-suite(qa) both found the profile unprompted and read all 5 subtasksestimationfound the profile itself and widened three task ranges on⚠️ Partialareas with the assumption named on each line. This was the original silent failure.Known cosmetic issues
Left as-is — the facts, tags and citations are correct in both cases:
<h2>on a first write and<strong>after a delta, so a profile's look changes once updated20 Aug-2026Follow-ups found, deliberately not fixed here
user-storyamend mode cannot repair a story that failed the readiness gate. Mode A only authors into an empty task, Mode B refuses anything NOT READY — so a gated story can only be fixed by hand-editing Asana, including one the skill itself wrote. Hit live during testing and worked around with an explicit override.estimationwidened three tasks by roughly 1.5h for a decision this PR implements.Known cost of this home
An Asana home means no version history. A Drive doc keeps every revision automatically; an overwritten Asana description keeps none — confirmed, nothing appears in the task's story feed. The delta comment records what changed and why, but not the previous wording, and says so in the file. Worth knowing rather than discovering later.
Versions
core 0.18.0, pm 0.26.0, qa 0.11.0 — all above what
developmentcarries.🤖 Generated with Claude Code