aSPARK v0.3.0 — situational lenses
Adds a situational layer on top of the SPARK loop: the process now adapts to what kind of software you're building, so relevant concerns get scrutinized and irrelevant ones stay quiet. Fully backward compatible — a project without a profile behaves exactly as before, because no lens is ever applied without one.
✨ New
- Project profile — the constitution gains a Project Profile & Active Lenses section recording the project's type (
website,web-app,api,cli,library) and its characteristics (handles-auth,is-public,handles-payments,handles-pii,has-database,is-multilingual). The Facilitator grounds both in the repo's real signals with evidence; the user confirms. A project can be several types and carry several characteristics. - Eight lenses — situational checklists the existing agents apply in the phases they own. Lenses are knowledge, not roles: no new agents, no new ceremonies.
seo— indexability, SSR vs client-only render, per-page metadata, structured data, Core Web Vitalsux— flow efficiency, empty/loading/error/success states, forms, responsive & touchapi— resource design, error-envelope consistency, versioning & breaking-change detection, auth surfacecli— help clarity, stdout/stderr discipline, exit codes, safety flagslibrary— public API surface, semver & deprecation discipline, packaging & footprintsecurity— header/transport hardening, auth lifecycle, authz matrix, supply chain, PII/privacyi18n— externalized strings, locale-aware formatting, text-expansion & RTL layoutdata— migration safety, integrity & transactions, indexing at scale, retention & recovery
- Two trigger axes — a lens activates from the type (
seo←website,ux←web-app,api←api,cli←cli,library←library) or from a characteristic (security←auth/public/payments/PII,i18n←multilingual,data←database). Security is a property of what software does with data, not of its shape — so it binds to behavior, not type. - Traceability, not assertion — a lens concern becomes a measurable
NFR-in Specify and is verified downstream under the same ID, riding the existing gates. Nothing is raised in one phase and quietly dropped in the next. - Constitution as single source of truth — the profile is the only place a lens is switched on, so phases can't drift from one another. With no constitution, a phase gives a one-line nudge toward
/charterand applies nothing. - Lens load flag — no cap on stacking; at 4+ active lenses the profile flags the elevated load, because visibility is the throttle.
- Add-a-file extensibility — a new concern is a new file in
lenses/plus a profile entry. Skills pass active lens paths generically, so no agent or skill is rewritten.
🔧 Changed
- Templates:
constitution.mdgains the Project Profile & Active Lenses section and the load flag;spec.mdnotes that active-lens concerns land as measurable NFRs. - Agents: facilitator detects type + characteristics and derives active lenses; product-owner captures lens concerns as NFRs; designer applies
ux/seo/i18n; reviewer verifies each lens's review slice in the diff; qa-tester verifies the browser-observable slice (ux,seo,security,i18n). - Skills:
/chartersurfaces the profile and load as the user's decision;/story-time,/look-and-feel,/peer-review,/demo-dayresolve active lenses from the constitution and pass their paths;/sparknudges toward/charterwhen no profile exists. - Docs:
docs/workflow.mdgains a Situational Concerns section; newlenses/README.mddocuments the lens contract, both trigger axes, and the detection signals.
✅ Validation
- Dogfooded through aSPARK's own loop. The feature was run through
/story-timebefore release (.spark/situational-lenses/spec.md). The Product Owner's Clarify pass caught two real defects in the first cut, both fixed before this shipped:- the no-constitution fallback was duplicated across three skills and re-derived lens logic per phase (drift-prone) — now nudge-only;
- nothing surfaced when many lenses stack — now flagged at 4+.
- All eight lens files conform to the documented contract (frontmatter, per-phase owner map, falsifiable checks only).
⚠️ Known limits (recorded, not papered over)
- Non-UI lenses have no QA surface.
api,cli,libraryanddatacontribute zero/demo-daychecks — the QA phase is browser-shaped and they have no browser to click. Their verification is Specify, Review and the increment's own tests. This is a pre-existing limitation of the loop that the lens layer makes visible rather than hides. - Lens compliance is instruction-driven. No test enforces that a lens actually fired; a silently-skipped lens looks like a correct N/A. The human gate is the only check.
- The success signal is not yet proven. The feature's own spec defines success as a UI lens firing and being QA-verified on a
websiteplus a Review lens firing and being Review-verified on anapi, both under the sameNFR-. Neither has been demonstrated by a full loop run yet.
Full changelog: v0.2.0...v0.3.0