Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 34 additions & 28 deletions .specify/research/repository-research.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@
### Size and Test Surface

- Code files (`ts/tsx/js/jsx/mjs/cjs`) across `universal`, `platforms`, `lib`, `implementations`:
`328`
- Code LOC across same surface: `33,606`
`357`
- Code LOC across same surface: `37,084`
- Unit test files in SDK and shared libraries (`universal`, `platforms`, `lib`): `35`
- Implementation test/e2e files (`implementations`): `16`
- Implementation test/e2e files (`implementations`): `20`

### Top-Level Responsibilities

Expand All @@ -55,20 +55,21 @@

| Package | Path | Layer | Approx LOC | Test Files |
| -------------------------------------------- | ---------------------------------------- | ------------------------ | ---------: | ---------: |
| `@contentful/optimization-api-schemas` | `universal/api-schemas` | Contracts | 2,280 | 0 |
| `@contentful/optimization-api-client` | `universal/api-client` | Transport client | 3,334 | 7 |
| `@contentful/optimization-core` | `universal/core` | Runtime core | 7,371 | 12 |
| `@contentful/optimization-node` | `platforms/javascript/node` | Platform adapter | 465 | 1 |
| `@contentful/optimization-web` | `platforms/javascript/web` | Platform adapter | 4,034 | 5 |
| `@contentful/optimization-web-preview-panel` | `platforms/javascript/web-preview-panel` | Preview tooling | 1,413 | 0 |
| `@contentful/optimization-react-native` | `platforms/javascript/react-native` | Platform adapter | 9,280 | 6 |
| `logger` | `lib/logger` | Internal utility | 462 | 2 |
| `mocks` | `lib/mocks` | Internal testing infra | 1,051 | 0 |
| `build-tools` | `lib/build-tools` | Internal build helpers | 293 | 2 |
| `@contentful/optimization-api-schemas` | `universal/api-schemas` | Contracts | 2,791 | 1 |
| `@contentful/optimization-api-client` | `universal/api-client` | Transport client | 3,406 | 7 |
| `@contentful/optimization-core` | `universal/core` | Runtime core | 7,205 | 11 |
| `@contentful/optimization-node` | `platforms/javascript/node` | Platform adapter | 505 | 1 |
| `@contentful/optimization-web` | `platforms/javascript/web` | Platform adapter | 4,346 | 5 |
| `@contentful/optimization-web-preview-panel` | `platforms/javascript/web-preview-panel` | Preview tooling | 1,863 | 0 |
| `@contentful/optimization-react-native` | `platforms/javascript/react-native` | Platform adapter | 9,683 | 6 |
| `logger` | `lib/logger` | Internal utility | 682 | 2 |
| `mocks` | `lib/mocks` | Internal testing infra | 1,190 | 0 |
| `build-tools` | `lib/build-tools` | Internal build helpers | 393 | 2 |
| `@implementation/node-ssr-only` | `implementations/node-ssr-only` | Reference implementation | 389 | 2 |
| `@implementation/node-ssr-web-vanilla` | `implementations/node-ssr-web-vanilla` | Reference implementation | 461 | 4 |
| `@implementation/web-vanilla` | `implementations/web-vanilla` | Reference implementation | 282 | 3 |
| `@implementation/react-native` | `implementations/react-native` | Reference implementation | 2,491 | 7 |
| `@implementation/web-react` | `implementations/web-react` | Reference implementation | 1,264 | 4 |
| `@implementation/react-native` | `implementations/react-native` | Reference implementation | 2,624 | 7 |

### Internal Dependency Direction (Validated)

Expand Down Expand Up @@ -107,7 +108,7 @@ graph LR
A --> J
```

- Local package graph is acyclic (`cycle: no` in validation script).
- Local package graph is acyclic (`cycle: no` from current manifest graph validation).
- `pnpm-workspace.yaml` includes `lib/*`, `platforms/javascript/*`, `universal/*`; implementations
are intentionally outside workspace and consume packed SDK tarballs via overrides.

Expand Down Expand Up @@ -136,16 +137,17 @@ graph LR
consent).
- preview bridge method `registerPreviewPanel()` returns mutable `signals` and `signalFns`.

### 3) Consent, Blocking, and Duplication Semantics
### 3) Consent and Blocking Semantics

- `ProductBase` defaults pre-consent allow-list to `['page', 'identify']`.
- Stateful products normalize `trackComponentView`/`trackFlagView` to `component` for allow-list
evaluation.
- Guarding is method-level via stage-3 decorator `@guardedBy`:
- synchronous predicate gating.
- optional `onBlocked` hook.
- blocked async methods return `Promise<undefined>` to preserve call shape.
- Blocked event payload is structured and emitted to signal/callback:
- `{ reason: 'consent'|'duplication', product, method, args }`.
- Duplication is handled via scoped `ValuePresence` detector for component/flag view methods.
- `{ reason: 'consent', product, method, args }`.

### 4) Stateful Queue and Flush Behavior

Expand Down Expand Up @@ -315,7 +317,8 @@ graph LR
- Main pipeline (`.github/workflows/main-pipeline.yaml`):
- path-filtered change detection for build/unit/e2e workloads,
- install/setup, license checks, format, build, typecheck, lint, package-matrix unit tests,
- per-implementation e2e jobs including dedicated RN Android emulator lane.
- per-implementation e2e jobs (`node-ssr-only`, `node-ssr-web-vanilla`, `web-vanilla`,
`web-react`) plus dedicated RN Android emulator lane.
- Publish workflow (`publish-npm.yaml`):
- release/manual dispatch,
- version derivation from tag,
Expand All @@ -331,6 +334,7 @@ graph LR
- Node SSR only,
- Node SSR + Web vanilla,
- Web vanilla,
- Web React + Web SDK,
- React Native (Detox Android lane in CI).
- Constitution explicitly positions reference implementations as required verification gates for
user-visible behavior changes.
Expand Down Expand Up @@ -376,7 +380,7 @@ graph LR
### DEC-005: Guard behavior is decorator-based and synchronous

- `status`: `accepted`
- `decision`: Use stage-3 `@guardedBy` wrappers for consent/duplication guard composition.
- `decision`: Use stage-3 `@guardedBy` wrappers for consent guard composition.
- `rationale`: Consistent guard semantics without repeated inline guard logic.
- `alternatives_considered`: inline method-level checks; middleware chains per product.
- `consequences`: decorator support required in build pipeline.
Expand Down Expand Up @@ -457,19 +461,20 @@ graph LR

### RSK-001: SpecKit template bootstrap is incomplete

- `severity`: `medium`
- `evidence`: constitution sync report flags missing `.specify/templates/*` artifacts and command
templates.
- `severity`: `low`
- `evidence`: `.specify/templates/commands/` artifacts referenced by constitution sync guidance are
still absent.
- `impact`: plan/spec/task workflows cannot be fully constitution-enforced through local template
checks.
- `mitigation`: bootstrap the missing template set and wire compliance checks into contributor
workflow.
command checks.
- `mitigation`: add the missing command template set under `.specify/templates/commands/` and wire
compliance checks into contributor workflow.

### RSK-002: Contract and preview packages have thin direct unit-test coverage

- `severity`: `medium`
- `evidence`:
- `universal/api-schemas` has no unit test suite.
- `universal/api-schemas` has a unit suite, but coverage is narrow (validation utility-centric;
limited direct schema-shape edge tests).
- `platforms/javascript/web-preview-panel` has no unit test suite (`test:unit` is TODO/no-op).
- `impact`: schema regressions or preview override regressions may primarily surface via downstream
integration tests.
Expand All @@ -489,7 +494,8 @@ graph LR
## Appendix B: Quality and Delivery Snapshot

- Main CI lanes: `setup`, `license-check`, `format`, `build`, `type-check`, `lint`, per-package unit
matrix, per-implementation e2e.
matrix, per-implementation e2e (`node-ssr-only`, `node-ssr-web-vanilla`, `web-vanilla`,
`web-react`, `react-native`).
- RN Android e2e lane provisions emulator, mock server, Metro bundler, and runs Detox suites.
- Publish lane bumps package versions from release tags and publishes built artifacts after
build/pack steps.
Expand Down
166 changes: 166 additions & 0 deletions .specify/scripts/bash/check-prerequisites.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
#!/usr/bin/env bash

# Consolidated prerequisite checking script
#
# This script provides unified prerequisite checking for Spec-Driven Development workflow.
# It replaces the functionality previously spread across multiple scripts.
#
# Usage: ./check-prerequisites.sh [OPTIONS]
#
# OPTIONS:
# --json Output in JSON format
# --require-tasks Require tasks.md to exist (for implementation phase)
# --include-tasks Include tasks.md in AVAILABLE_DOCS list
# --paths-only Only output path variables (no validation)
# --help, -h Show help message
#
# OUTPUTS:
# JSON mode: {"FEATURE_DIR":"...", "AVAILABLE_DOCS":["..."]}
# Text mode: FEATURE_DIR:... \n AVAILABLE_DOCS: \n ✓/✗ file.md
# Paths only: REPO_ROOT: ... \n BRANCH: ... \n FEATURE_DIR: ... etc.

set -e

# Parse command line arguments
JSON_MODE=false
REQUIRE_TASKS=false
INCLUDE_TASKS=false
PATHS_ONLY=false

for arg in "$@"; do
case "$arg" in
--json)
JSON_MODE=true
;;
--require-tasks)
REQUIRE_TASKS=true
;;
--include-tasks)
INCLUDE_TASKS=true
;;
--paths-only)
PATHS_ONLY=true
;;
--help|-h)
cat << 'EOF'
Usage: check-prerequisites.sh [OPTIONS]
Consolidated prerequisite checking for Spec-Driven Development workflow.
OPTIONS:
--json Output in JSON format
--require-tasks Require tasks.md to exist (for implementation phase)
--include-tasks Include tasks.md in AVAILABLE_DOCS list
--paths-only Only output path variables (no prerequisite validation)
--help, -h Show this help message
EXAMPLES:
# Check task prerequisites (plan.md required)
./check-prerequisites.sh --json
# Check implementation prerequisites (plan.md + tasks.md required)
./check-prerequisites.sh --json --require-tasks --include-tasks
# Get feature paths only (no validation)
./check-prerequisites.sh --paths-only
EOF
exit 0
;;
*)
echo "ERROR: Unknown option '$arg'. Use --help for usage information." >&2
exit 1
;;
esac
done

# Source common functions
SCRIPT_DIR="$(CDPATH="" cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/common.sh"

# Get feature paths and validate branch
eval $(get_feature_paths)
check_feature_branch "$CURRENT_BRANCH" "$HAS_GIT" || exit 1

# If paths-only mode, output paths and exit (support JSON + paths-only combined)
if $PATHS_ONLY; then
if $JSON_MODE; then
# Minimal JSON paths payload (no validation performed)
printf '{"REPO_ROOT":"%s","BRANCH":"%s","FEATURE_DIR":"%s","FEATURE_SPEC":"%s","IMPL_PLAN":"%s","TASKS":"%s"}\n' \
"$REPO_ROOT" "$CURRENT_BRANCH" "$FEATURE_DIR" "$FEATURE_SPEC" "$IMPL_PLAN" "$TASKS"
else
echo "REPO_ROOT: $REPO_ROOT"
echo "BRANCH: $CURRENT_BRANCH"
echo "FEATURE_DIR: $FEATURE_DIR"
echo "FEATURE_SPEC: $FEATURE_SPEC"
echo "IMPL_PLAN: $IMPL_PLAN"
echo "TASKS: $TASKS"
fi
exit 0
fi

# Validate required directories and files
if [[ ! -d "$FEATURE_DIR" ]]; then
echo "ERROR: Feature directory not found: $FEATURE_DIR" >&2
echo "Run /speckit.specify first to create the feature structure." >&2
exit 1
fi

if [[ ! -f "$IMPL_PLAN" ]]; then
echo "ERROR: plan.md not found in $FEATURE_DIR" >&2
echo "Run /speckit.plan first to create the implementation plan." >&2
exit 1
fi

# Check for tasks.md if required
if $REQUIRE_TASKS && [[ ! -f "$TASKS" ]]; then
echo "ERROR: tasks.md not found in $FEATURE_DIR" >&2
echo "Run /speckit.tasks first to create the task list." >&2
exit 1
fi

# Build list of available documents
docs=()

# Always check these optional docs
[[ -f "$RESEARCH" ]] && docs+=("research.md")
[[ -f "$DATA_MODEL" ]] && docs+=("data-model.md")

# Check contracts directory (only if it exists and has files)
if [[ -d "$CONTRACTS_DIR" ]] && [[ -n "$(ls -A "$CONTRACTS_DIR" 2>/dev/null)" ]]; then
docs+=("contracts/")
fi

[[ -f "$QUICKSTART" ]] && docs+=("quickstart.md")

# Include tasks.md if requested and it exists
if $INCLUDE_TASKS && [[ -f "$TASKS" ]]; then
docs+=("tasks.md")
fi

# Output results
if $JSON_MODE; then
# Build JSON array of documents
if [[ ${#docs[@]} -eq 0 ]]; then
json_docs="[]"
else
json_docs=$(printf '"%s",' "${docs[@]}")
json_docs="[${json_docs%,}]"
fi

printf '{"FEATURE_DIR":"%s","AVAILABLE_DOCS":%s}\n' "$FEATURE_DIR" "$json_docs"
else
# Text output
echo "FEATURE_DIR:$FEATURE_DIR"
echo "AVAILABLE_DOCS:"

# Show status of each potential document
check_file "$RESEARCH" "research.md"
check_file "$DATA_MODEL" "data-model.md"
check_dir "$CONTRACTS_DIR" "contracts/"
check_file "$QUICKSTART" "quickstart.md"

if $INCLUDE_TASKS; then
check_file "$TASKS" "tasks.md"
fi
fi
Loading