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
32 changes: 32 additions & 0 deletions docs/sops/SOP-101-frame-lifecycle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# SOP-101 Frame Lifecycle

**Owner:** Platform Team
**Status:** Active
**Related PROSE Expectation:** [E.1 Frame stack integrity](../specs/PROSE-platform-overview.md#e1-frame-stack-integrity)

## Objective
Ensure context frames are created, activated, and closed in a deterministic, non-circular order so that only one frame is active at a time.

## Procedure

1. **Frame creation**
- A frame is created with a unique name, type, and optional parent frame.
- The newly created frame becomes the active frame.

2. **Frame activation**
- Only the most recently pushed frame may be active.
- Previous frames remain in the stack but are inactive.

3. **Frame closure**
- Closing a frame removes it from the top of the stack.
- The previous frame automatically becomes active.
- No frame may reference itself as a parent, directly or transitively.

## Verification

- Run integration test: `active frame stack remains consistent`
- Expected result: after pushing frames A → B → C and popping twice, only A remains active.

## Non-compliance

Orphaned active frames, circular parent references, or multiple simultaneous active frames are considered non-compliant and must fail validation.
30 changes: 30 additions & 0 deletions docs/sops/SOP-102-decision-record-keeping.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# SOP-102 Decision Record Keeping

**Owner:** Platform Team
**Status:** Active
**Related PROSE Expectation:** [E.2 Decision immutability](../specs/PROSE-platform-overview.md#e2-decision-immutability)

## Objective
Preserve decisions as tamper-evident audit records so that historical rationale remains trustworthy across sessions.

## Procedure

1. **Recording a decision**
- Capture title, rationale, timestamp, and author context.
- Assign a stable identifier at creation time.

2. **Storage**
- Store the decision in the project-local SQLite database.
- Do not overwrite existing decision records.

3. **Retrieval**
- Decisions must be retrievable by identifier, title, or full-text search.

## Verification

- Run integration test: `recorded decisions are immutable`
- Expected result: re-adding a decision with the same title creates a new record; the original rationale remains unchanged.

## Non-compliance

Mutating an existing decision's title, rationale, or identifier is non-compliant.
30 changes: 30 additions & 0 deletions docs/sops/SOP-103-project-boundary-enforcement.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# SOP-103 Project Boundary Enforcement

**Owner:** Platform Team
**Status:** Active
**Related PROSE Expectation:** [E.3 Project isolation](../specs/PROSE-platform-overview.md#e3-project-isolation)

## Objective
Prevent context leakage between projects so that each project directory owns an independent memory store.

## Procedure

1. **Project initialization**
- Create a `.stackmemory/` directory inside the target project directory.
- Store all project-specific data within that directory.

2. **Operation scoping**
- Resolve the active project by the current working directory.
- Do not search parent directories for sibling project stores.

3. **Cross-project sync**
- Context may only be shared between projects through explicit, user-initiated sync commands.

## Verification

- Run integration test: `projects in different directories are isolated`
- Expected result: a decision recorded in project A is not visible in project B.

## Non-compliance

Reading or writing another project's data without explicit sync is non-compliant.
29 changes: 29 additions & 0 deletions docs/sops/SOP-201-cli-exit-code-compliance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# SOP-201 CLI Exit-Code Compliance

**Owner:** CLI Team
**Status:** Active
**Related PROSE Expectation:** [E.4 CLI contract](../specs/PROSE-platform-overview.md#e4-cli-contract)

## Objective
Provide deterministic exit codes so that scripts, CI pipelines, and automation tools can rely on CLI outcomes.

## Procedure

1. **Success**
- Return exit code `0` when a command completes its intended function.

2. **Failure**
- Return a non-zero exit code when a command cannot complete its intended function.
- Include a human-readable error message on stderr or stdout.

3. **Documentation**
- Document exit-code behavior for commands used in automation.

## Verification

- Run integration test: `CLI commands return correct exit codes`
- Expected result: successful commands exit `0`; invalid commands exit non-zero.

## Non-compliance

Returning `0` on failure or a non-zero code on success is non-compliant.
30 changes: 30 additions & 0 deletions docs/sops/SOP-202-data-portability.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# SOP-202 Data Portability

**Owner:** Platform Team
**Status:** Active
**Related PROSE Expectation:** [E.5 SQLite contract](../specs/PROSE-platform-overview.md#e5-sqlite-contract)

## Objective
Ensure the project memory store is self-contained and portable across machines without external dependencies.

## Procedure

1. **Self-contained storage**
- Keep the primary database file inside `.stackmemory/`.
- Avoid reliance on remote databases for core context storage.

2. **Schema compatibility**
- Maintain forward-compatible schemas within major CLI versions.
- Document migration steps when schema changes are required.

3. **Backup and restore**
- A user must be able to copy `.stackmemory/` to another machine and resume work with the same CLI version.

## Verification

- Run integration test: `SQLite database is self-contained in .stackmemory`
- Expected result: after initialization and recording context, a `.db` or `.sqlite` file exists under `.stackmemory/`.

## Non-compliance

Requiring external services for basic context retrieval or scattering state outside `.stackmemory/` is non-compliant.
75 changes: 54 additions & 21 deletions docs/specs/PROSE-platform-overview.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
# PROSE Platform Overview

> PROSE = **P**urpose, **R**ules & Constraints, **O**bservables, **S**cenarios, **E**xpectations
>
> Expectations are grounded in **SOPs** — Standard Operating Procedures that define repeatable business outcomes and standardized outputs.

This document describes StackMemory's platform behavior in plain English. Each section is intentionally testable and maps directly to integration tests in `src/__tests__/integration/platform-overview.test.ts`.

The contract layer of PROSE is derived from SOPs: every Expectation below corresponds to a procedural guarantee that QA can validate and that can be turned into executable scripts.

---

## P — Purpose
Expand Down Expand Up @@ -71,44 +75,73 @@ Capturing a snapshot persists the current context state for later handoff.

## E — Expectations

Properties that must always hold true and guarantees the platform makes to users and integrations.
Properties that must always hold true and guarantees the platform makes to users and integrations. Each Expectation is backed by one or more SOPs so that business outcomes can be standardized, QA'd, and automated.

### E.1 Frame stack integrity
At any time, there is at most one active frame, and the frame stack is non-circular.

**SOP basis:** `SOP-101 Frame Lifecycle` — frames must be pushed and popped in a deterministic order; no orphaned active frames are allowed.

### E.2 Decision immutability
Once recorded, a decision's identifier, title, and rationale must not change.

**SOP basis:** `SOP-102 Decision Record Keeping` — decisions are audit records and must remain tamper-evident.

### E.3 Project isolation
Two projects initialized in different directories must not share context unless explicitly synced.

**SOP basis:** `SOP-103 Project Boundary Enforcement` — each project directory owns its SQLite database and must not leak state into neighboring projects.

### E.4 CLI contract
All CLI commands return a zero exit code on success and a non-zero exit code on failure, with human-readable output.

**SOP basis:** `SOP-201 CLI Exit-Code Compliance` — scripts and CI pipelines depend on reliable exit codes.

### E.5 SQLite contract
The local SQLite database is self-contained within `.stackmemory/` and portable across machines with the same CLI version.

**SOP basis:** `SOP-202 Data Portability` — the database must be relocatable and restorable without external services.

---

## SOP → PROSE → Tests workflow

```
SOP (business outcome)
PROSE Expectation (plain-English contract)
Integration test (executable validation)
Feature-script parity (automation)
```

For example, `SOP-101 Frame Lifecycle` becomes PROSE `E.1`, which becomes the test `active frame stack remains consistent`. QA can run the same test suite to verify SOP compliance, and the test can be used to generate or validate automation scripts.

---

## Test mapping

| PROSE ID | Test case |
|----------|-----------|
| P.1 | `initializes a project with stackmemory init` |
| P.2 | `retrieves decisions across sessions` |
| R.1 | `fails gracefully outside an initialized project` |
| R.2 | `returns empty results for non-matching search` |
| R.3 | `init is idempotent` |
| O.1 | `reports status for initialized and uninitialized projects` |
| O.2 | `lists pushed frames` |
| O.3 | `lists recorded decisions` |
| O.4 | `searches stored context` |
| S.1 | `pushing a frame creates a scoped entry` |
| S.2 | `popping a frame restores the previous frame` |
| S.3 | `recording a decision persists rationale` |
| S.4 | `capturing a snapshot persists handoff state` |
| E.1 | `active frame stack remains consistent` |
| E.2 | `recorded decisions are immutable` |
| E.3 | `projects in different directories are isolated` |
| E.4 | `CLI commands return correct exit codes` |
| E.5 | `SQLite database is self-contained in .stackmemory` |
| PROSE ID | SOP basis | Test case |
|----------|-----------|-----------|
| P.1 | — | `initializes a project with stackmemory init` |
| P.2 | — | `retrieves decisions across sessions` |
| R.1 | — | `fails gracefully outside an initialized project` |
| R.2 | — | `returns empty results for non-matching search` |
| R.3 | — | `init is idempotent` |
| O.1 | — | `reports status for initialized and uninitialized projects` |
| O.2 | — | `lists pushed frames` |
| O.3 | — | `lists recorded decisions` |
| O.4 | — | `searches stored context` |
| S.1 | — | `pushing a frame creates a scoped entry` |
| S.2 | — | `popping a frame restores the previous frame` |
| S.3 | — | `recording a decision persists rationale` |
| S.4 | — | `capturing a snapshot persists handoff state` |
| E.1 | `SOP-101 Frame Lifecycle` | `active frame stack remains consistent` |
| E.2 | `SOP-102 Decision Record Keeping` | `recorded decisions are immutable` |
| E.3 | `SOP-103 Project Boundary Enforcement` | `projects in different directories are isolated` |
| E.4 | `SOP-201 CLI Exit-Code Compliance` | `CLI commands return correct exit codes` |
| E.5 | `SOP-202 Data Portability` | `SQLite database is self-contained in .stackmemory` |
14 changes: 9 additions & 5 deletions src/__tests__/integration/platform-overview.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,9 +263,13 @@ describe('PROSE Platform Overview', { timeout: 60_000 }, () => {

// ---------------------------------------------------------------------------
// E — Expectations
//
// Each Expectation is grounded in an SOP (Standard Operating Procedure) so
// that business outcomes can be standardized, QA'd, and automated.
// SOP source: docs/sops/
// ---------------------------------------------------------------------------

describe('E.1 Frame stack integrity', () => {
describe('E.1 Frame stack integrity (SOP-101)', () => {
it('active frame stack remains consistent', () => {
run('init', testDir);
run('context push "Alpha frame"', testDir);
Expand All @@ -282,7 +286,7 @@ describe('PROSE Platform Overview', { timeout: 60_000 }, () => {
});
});

describe('E.2 Decision immutability', () => {
describe('E.2 Decision immutability (SOP-102)', () => {
it('recorded decisions are immutable', () => {
run('init', testDir);
run(
Expand All @@ -304,7 +308,7 @@ describe('PROSE Platform Overview', { timeout: 60_000 }, () => {
});
});

describe('E.3 Project isolation', () => {
describe('E.3 Project isolation (SOP-103)', () => {
it('projects in different directories are isolated', () => {
const projectA = path.join(testDir, 'project-a');
const projectB = path.join(testDir, 'project-b');
Expand All @@ -322,7 +326,7 @@ describe('PROSE Platform Overview', { timeout: 60_000 }, () => {
});
});

describe('E.4 CLI contract', () => {
describe('E.4 CLI contract (SOP-201)', () => {
it('CLI commands return correct exit codes', () => {
expect(() => run('init', testDir)).not.toThrow();
expect(() => run('decision list', testDir)).not.toThrow();
Expand All @@ -332,7 +336,7 @@ describe('PROSE Platform Overview', { timeout: 60_000 }, () => {
});
});

describe('E.5 SQLite contract', () => {
describe('E.5 SQLite contract (SOP-202)', () => {
it('SQLite database is self-contained in .stackmemory', () => {
run('init', testDir);
run('decision add "DB test" --why "Check local DB"', testDir);
Expand Down
Loading