Install
$ agentstack add skill-big-emotion-agent-atelier-project-standard-spec ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Big Emotion Project Standard Spec
> M4 wiring pending for this repo — preconditions below will fail-fast until a Jira project + Confluence space are bootstrapped (run /project-standard:setup module M4, then project-standard-bootstrap-confluence).
Maintain the Big Emotion Project Standard spec tree on Confluence. Given a free-text problem (bug, feature, refinement idea), read Confluence (Requirements / Decisions / Architecture) as the canonical source of truth, structure the reflection, propose Pending REQ/DEC/ARCH sections plus matching Jira tickets in the project whose key is jiraProjectKey in docs/confluence-spec/config.json, then — after explicit confirmation — publish Confluence first, Jira second, and close the link loop both ways.
This skill is append-only on Confluence and only writes new sections at status Pending. Humans transition Pending → Implemented → Approved through the Confluence UI. The skill never touches the Status macro of an existing section, never edits the body of a non-Pending section, and never deletes an ID.
When to Activate
- User invokes
/project-standard-spec(explicit command). - User writes a natural-language prompt that signals a spec-level reflection:
bug : …/bug:/ "il y a un bug" / "the … is broken"j'aimerais ajouter …/ "je voudrais ajouter" / "we should add"feature idea …/ "feature idea" / "what if we"comment résoudre …/ "comment fixer" / "how do we handle"- Any free-text describing a problem, gap, or improvement that lacks a Jira ticket and that may touch a REQ/DEC/ARCH.
- Do not activate when:
- The user pastes a Jira ticket URL or key — that path belongs to
project-standard-ticket. - The user asks to flip a Status macro on an existing section (
Pending → Implemented, etc.) — that is a Confluence-UI-only operation, refuse and direct them there. - The user asks to bootstrap or repopulate the spec tree — that is
/project-standard-bootstrap-confluenceand runs only once.
If the trigger is ambiguous (the description could be either a pure code question or a spec change), default to activating: the worst case is the user replies with anything other than an affirmative token at Step 6 and nothing is written.
Inputs
A single free-text argument: a description of the change. The description can be a bug report, a feature idea, an architectural concern, or an open question. The skill turns it into structured REQ/DEC/ARCH drafts plus Jira tickets.
If the argument is empty, ask for the description before doing anything else (this is a clarification gate, not a safety blocker).
Preconditions (safety blockers — stop and report if any fail)
- Bootstrap sentinel exists —
docs/.confluence-bootstrap-completemust be present. If absent, stop and tell the user: Confluence has not been bootstrapped yet — run/project-standard-bootstrap-confluencefirst. - Config readable —
docs/confluence-spec/config.jsonmust be present and parseable, with non-null values forcloudId,siteUrl,spaceKey,engineeringRootPageId,requirementsPageId,decisionsPageId,architecturePageId,obsoletePageId,jiraProjectKey, andjiraIssueTypeIds.{Epic,Story,Task,Bug}. Any null in the four*PageIdfields means the bootstrap publish step was incomplete — stop. - Atlassian MCP reachable —
getAccessibleAtlassianResourcesreturns at least one site, and the site whose ID matchescloudIdis in the list. If not, stop — both halves of the workflow are impossible. - Atlassian identity resolvable —
atlassianUserInfosucceeds. Used to attribute the drafts to the current user. - Jira project visible —
getVisibleJiraProjectsincludes a project whose key isjiraProjectKey. If not, the user lacks access — stop. - Template available —
docs/templates/jira-ticket-template.mdexists. If absent, stop — the Jira tickets cannot be filled.
On a safety blocker: stop and report. Do not guess, do not skip a precondition, do not write anything.
Workflow
The full chain is read → investigate → dedupe → choose granularity → draft → preview → confirm → write Confluence → write Jira → close link → report. Steps 1–5 are pure reads + in-memory drafts and write nothing. Step 6 is the single hard gate. Steps 7–9 are the only writes the skill ever performs; they happen in strict order (Confluence first, Jira second, back-link last) so that any mid-chain failure leaves recoverable state. Step 10 is the report. Each step below restates its preconditions inline so the reader does not have to scroll.
Step 1 — Read config
- Load
docs/confluence-spec/config.json. Extract every field listed in precondition 2. - Verify
docs/.confluence-bootstrap-completeexists. If missing, stop. - Read
docs/templates/jira-ticket-template.mdinto memory so it can be applied per-ticket in Step 5. - Resolve
cloudIdviagetAccessibleAtlassianResourcesand cross-check it matches the config; resolve ownaccountIdviaatlassianUserInfo(informational — this skill does not self-assign anything).
Step 2 — Investigate
- Read the user's description. Ask ONE clarification question if and only if the shape of the change is genuinely ambiguous — e.g. you cannot tell whether it is a bug (existing REQ broken) or a feature (new REQ needed). Otherwise, state your assumptions explicitly and proceed.
- Fetch the engineering root and its descendants:
getConfluencePage(cloudId, pageId=engineeringRootPageId)→ confirm the tree shape.getConfluencePageDescendants(cloudId, parentId=engineeringRootPageId)→ list the four canonical subpages (Requirements / Decisions / Architecture / Obsolete, possibly carrying the project's title prefix). Identify them by the*PageIdvalues fromconfig.json, never by title — a shared Confluence space may host another project's spec tree whose pages own similar titles.- For each of
requirementsPageId,decisionsPageId,architecturePageId:getConfluencePage(full body) to retrieve the existing REQ/DEC/ARCH sections and their IDs. - Walk the impact graph
REQ ← DEC ← ARCH: if a candidate change touches an ARCH, list every DEC that references it; if it touches a DEC, list every REQ that depends on it. Propagation goes upward from ARCH to DEC to REQ. Surface the propagated impact in the preview. - Detection is text-based: an ARCH is "referenced" by a DEC if the DEC body contains its ID (
ARCH-007); a DEC is referenced by a REQ the same way. UsesearchConfluenceUsingCqlscoped to the engineering root withtext ~ ""if a full body scan is impractical. - Worked example: a request to introduce server-side caching that proposes
NEW ARCH-008 (HTTP cache layer)andNEW DEC-019 (cache strategy = stale-while-revalidate)is propagated as: ARCH-008 has no ancestor (it's new); DEC-019 references ARCH-008; any REQ whose statement names latency or freshness gets flagged for review even if untouched, so the human reviewer can decide whether aRETIREorEDITis in order. - Note any section you would propose to
RETIREand record its current Status — onlyPendingsections may be edited; non-Pendingsections can only be marked for retirement via a successor (see Safeguards).
Step 3 — Search for duplicates
searchConfluenceUsingCqlagainstspace = "" AND ancestor = AND text ~ ""for each candidate ID, to confirm no REQ/DEC/ARCH ID being proposed is already in use anywhere in the tree.searchJiraIssuesUsingJqlagainstproject = AND statusCategory != Done AND text ~ ""for each candidate REQ/DEC/ARCH ID, to confirm no open ticket already covers the same scope.- If a duplicate is found, fold the draft into the existing artifact (point at it in the preview, do not create a parallel ID) and tell the user.
- Additionally, before allocating a new ID in Step 5, run one CQL query per type (
REQ,DEC,ARCH) to confirm the highest existing suffix. This double-check is the only safeguard against a stale local view of the engineering root (Step 2's body fetch could miss a section added by another writer between Step 2 and Step 5). - The dedupe step is purely informational — it never mutates Confluence or Jira. If the user wants to override a duplicate (e.g. the existing artifact is genuinely orthogonal despite a text match), they say so at Step 6 and the skill proceeds with the new ID; the override is logged in the Step 10 report.
Step 4 — Granularity decision
Decide the Jira shape from the shape of the Confluence change, not the code size. Use this table verbatim:
| Confluence change | Jira artifact | | --- | --- | | ≥2 REQ touched OR new ARCH + ≥2 DEC | Epic + Stories | | 1 REQ touched (NEW or EDIT) ± ≤1 DEC | Story | | Correction of a failing test against an existing REQ, no spec change | Task or Bug | | Editorial-only Jira refinement (no REQ/DEC/ARCH change) | no ticket — reference the existing one |
Pick exactly one row. When Epic + Stories applies, the Epic is the parent and each touched REQ gets one Story child. Tasks and Bugs are leaf tickets with no parent unless they belong to an Epic from the same session.
Rules of thumb to disambiguate:
- A purely cosmetic copy or wording change with no REQ touched →
Editorial-only Jira refinement→ no new ticket and no Confluence write; point at the existing ticket (if any) in the Step 6 preview and Step 10 report. Commenting on that ticket stays a human action — this skill never writes to existing tickets. - A bug that proves an existing REQ is wrong (the spec is correct, the code is wrong) →
Task or Bug. Do not edit the REQ. - A bug that proves an existing REQ is misleading (the code matches the spec but the spec is wrong) →
Storywith anEDIT statementon the REQ. - A new behaviour that did not exist in any previous spec →
Storywith aNEWREQ. - A new behaviour that requires a structural change (new runtime surface, new module boundary, new shared infra) →
Epic + Storieswith aNEWARCH and ≥1NEWDEC explaining the choice.
When in doubt, choose the lighter artifact (Story over Epic, Task over Story) — humans can split it later via Confluence UI + Jira, but the skill never auto-merges.
Step 5 — Draft everything
For each REQ/DEC/ARCH section to write:
- Allocate the next monotonic ID by reading the existing IDs from Confluence (Step 2). For each type, find the maximum suffix
Nalready published (e.g.REQ-042) and allocateN+1(REQ-043). Never reuse an ID. Never renumber an already-published ID. - Compose the section body with this canonical shape:
- REQ-NNN — \
Statement:modal verb preserved verbatim (must/must not/should).GWT:one or more Given / When / Then blocks.Status: Pending(Confluence Status macro, colour grey).Links → Jira:block (filled in Step 9).- DEC-NNN — \
Context / Decision / Alternatives / Tradeoffs / Requirements satisfied.Supersedes:if it retires an older decision.Status: Pending.- ARCH-NNN — \
Summary / Source files (expected) / Tests anchoring this contract.Status: Pending.
For each Jira ticket to create:
- Apply
docs/templates/jira-ticket-template.md, filling the conditional sections by issue type (Bug includes Reproduction + Expected vs Actual; Story includes User Story). - The Confluence impact section is load-bearing — use the exact format:
`` • REQ-042 — EDIT statement Current: "" Proposed: "" GWT changes: … • DEC-018 — NEW Context / Decision / Alternatives / Tradeoffs / Requirements satisfied • ARCH-007 — EDIT body Summary change / Source files (expected) / Tests anchoring this contract ` Allowed verbs are exactly NEW, EDIT, RETIRE` — nothing else.
- Include a placeholder for the Confluence anchor URL (filled at create time in Step 8 using
/wiki/spaces//pages/#). - The ticket title is concise and business-readable; it carries the primary touched ID in parentheses (e.g.
Search: keep filters across page reloads (REQ-042)).
Step 6 — Preview + approval gate (HARD)
Print all drafts. The preview block must contain:
Spec drafts ready for review.
Confluence sections (Pending) — N total
• REQ-043 — Statement: "" / GWT:
• DEC-019 — Context: / Decision: / Supersedes:
• ARCH-008 — Summary:
…
Jira tickets — M total (issue type from granularity table)
• [Story] (REQ-042)
Confluence impact:
• REQ-042 — EDIT statement / Current: "" / Proposed: "" / GWT changes: …
Body preview:
…
Impact propagation
• ARCH-005 (proposed EDIT) is referenced by DEC-011, DEC-014 → review their alignment
• REQ-042 (proposed RETIRE) → propose successor REQ-043 with Supersedes: REQ-042
Reply `create` / `go` / `ok` / `oui` / `valide` / `yes` to publish.
Anything else aborts. Silence aborts.
Wait for explicit confirmation. Affirmative tokens (case-insensitive): create, go, ok, oui, valide, yes. Anything else — including silence, partial answers, "let me check first", "tomorrow" — aborts. Implicit confirmation from a prior turn in the session does not count; the confirmation must arrive in response to the preview block above.
Step 7 — Confluence first
For each Pending section to publish, in deterministic order (Requirements → Decisions → Architecture, then Obsolete entries last):
getConfluencePage(cloudId, pageId=PageId, expand=body.storage,version)— capture the currentversion.number.updateConfluencePage(cloudId, pageId, version=, body=)— append the new section to the existing body. Never overwrite, never reorder existing content.- On
409/ version-mismatch error: re-fetch the page, re-allocate the ID (a competing writer may have takenREQ-043between read and write), reassemble the body, retry once. On a second mismatch, abort and surface the error verbatim — do not loop.
If a section is a RETIRE-successor, the predecessor is not edited here. The Obsolete page handles the predecessor as a separate appended entry in the same Step 7 pass (under the Obsolete subtree). The Status macro of the predecessor stays untouched — humans flip it via Confluence UI after the new spec is approved.
Step 8 — Then Jira
After all Confluence writes succeed (Confluence-first rule):
- If the granularity is
Epic + Stories,createJiraIssuethe Epic first usingjiraIssueTypeIds.Epic. Capture its key. - Create Stories next, each carrying
customfield_orparent.key =per the project's epic-link convention (the value comes from the template's frontmatter or from the issue type's create metadata if unknown). - Create Tasks and Bugs last as leaf tickets.
- Every ticket body includes a clickable Confluence heading-anchor URL of the form
/wiki/spaces//pages/#for each touched REQ/DEC/ARCH. The anchor is the section heading in Confluence's URL-slug form.
If a ticket creation fails mid-sequence, stop and report the partial state (which tickets exist, which Confluence sections exist) so the user can reconcile manually. Do not retry blindly. An orphan Confluence section is recoverable (humans can attach a ticket later via UI); an orphan Jira ticket is harder to clean up, which is why Confluence comes first.
Step 9 — Close the loop
For each Confluence section touched in Step 7, re-updateConfluencePage (version+1) to append the created Jira key inside its Links → Jira: block:
Links → Jira: -1234, -1235
Use the same version-mismatch retry policy as Step 7 (one retry max, then abort verbatim). This closes the bidirectional link: section knows its ticket, ticket already knows its section from Step 8.
Step 10 — Return
End-of-turn report:
Spec maintainer published.
Confluence (Pending):
• REQ-043 → /wiki/spaces//pages/#REQ-043-
• DEC-019 → /w
…
## Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [big-emotion](https://github.com/big-emotion)
- **Source:** [big-emotion/agent-atelier](https://github.com/big-emotion/agent-atelier)
- **License:** MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.