Skip to content

feat: fix the Project Profile home to one Asana task per project - #61

Merged
ravi-solanki-31 merged 9 commits into
developmentfrom
feat/project-profile-asana-home
Sep 8, 2026
Merged

feat: fix the Project Profile home to one Asana task per project#61
ravi-solanki-31 merged 9 commits into
developmentfrom
feat/project-profile-asana-home

Conversation

@ravi-solanki-31

@ravi-solanki-31 ravi-solanki-31 commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Story

None. This implements Decision · Project Profile canonical home (Asana 1216550765662503). No board story was written for it, so there are no [AC]s to check against and scope-guard could 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 development and 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:

  • Its contract suite (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.
  • Its Profile lives at: completion line, which does the same job as this branch's Profile: line and reads better.
  • PR Feat/pm estimation feature list #56's rewrite of estimation into 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-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 the consumers did not stop when they could not find one:

  • estimation ran without profile-driven widening and emitted a confident range
  • recipes and ui-creation fell back to house defaults, ignoring overrides that existed
  • test-suite told QA to build a profile that was already there

All 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 in raftkit-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:

  • Onboarding takes the Asana project as an input and never infers it from a source's contents. A PRD quoting a board GID is content, not an instruction — that is how one client's facts land in another's board.
  • A roughly-typed project name is resolved against Asana rather than trusted: one match proceeds and shows what it matched, several ask which, none stops.
  • Every delta is recorded as one comment on the parent task. Asana keeps no history of an overwritten description — verified, its story feed stayed silent after five subtasks were rewritten. The comment records what changed and why. It is an audit trail, not a backup, and says so.
  • A write that times out is not a write that failed — look the task up by name before retrying, because a duplicate parent makes the lookup ambiguous for every consumer.
  • user-story states when it is not grounding a story in the profile, instead of omitting it silently.
  • user-story's frontmatter parses again. Its description contained amend mode: a diff-first…, and a colon-space ends a plain YAML scalar, so the skill was loading with all frontmatter dropped. Pre-existing on development; 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.

Before Now
Subtask name Glossary Glossary — what the project's terms mean
Section size ~45 facts in one subtask, seven headings inside it Splits past ~15 facts; headings inside a section mean those headings were the sections
Preamble The tag legend repeated in all five subtasks Legend on the parent once; each subtask opens with one line and a fact count
Fact length 80+ words, several points per bullet One sentence, inside the house 25-word limit — a fact needing three clauses becomes three facts, each with its own tag

Same 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 as Architecture &amp;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.sh34 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:

  • Write — parent + 5 subtasks, correct name and project, read-back clean
  • Formatting — facts as lists, no tables, conflicts as nested lists, allowed tags only, entities escaped
  • Refuses to infer a project from a source's contents, with the exact stop message
  • Delta — changed/new/conflicts rather than a rewrite, verified by diffing a subtask's previous content
  • Delta comment — posted on the parent in the specified shape
  • Readsstory-skill-generator (pm) and test-suite (qa) both found the profile unprompted and read all 5 subtasks
  • Profile-driven widening — the then-current estimation found the profile itself and widened three task ranges on ⚠️ Partial areas 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:

  • Section labels render as <h2> on a first write and <strong> after a delta, so a profile's look changes once updated
  • One subtask's date stamp came out as 20 Aug-2026

Follow-ups found, deliberately not fixed here

  1. user-story amend 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.
  2. PRD §10 Q3 is stale enough to pad estimates. It still lists the profile home as open, so a profile built from it records the fact as ❓ Missing and estimation widened 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 development carries.

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Aug 21, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: a2289f10-01d2-4501-9765-4b907b4dee49


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

ravi-solanki-31 and others added 4 commits August 21, 2026 15:37
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
ravi-solanki-31 force-pushed the feat/project-profile-asana-home branch from c6061d7 to 305cd9d Compare August 21, 2026 10:10
ravi-solanki-31 and others added 5 commits August 21, 2026 16:07
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 &amp;
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>
@ravi-solanki-31
ravi-solanki-31 merged commit 15bc708 into development Sep 8, 2026
2 checks passed
@ravi-solanki-31
ravi-solanki-31 deleted the feat/project-profile-asana-home branch September 8, 2026 13:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant