Skip to content
Draft
Show file tree
Hide file tree
Changes from 9 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
38 changes: 38 additions & 0 deletions .github/workflows/lotus-family-conformance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,51 @@ jobs:
persist-credentials: false

- name: Set up Python
id: python
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: "3.12"

- name: Run Lotus Family conformance suite
id: conformance
run: |
python -m unittest discover \
-s standards/lotus-family/conformance \
-p 'test_*.py' \
-v

- name: Emit immutable CI causal observation
if: always()
env:
LOTUS_COMMIT_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
Comment thread
safal207 marked this conversation as resolved.
Outdated
LOTUS_REF: ${{ github.head_ref || github.ref }}
LOTUS_CONCLUSION: ${{ steps.conformance.outcome }}
LOTUS_RUNNER_OS: ${{ runner.os }}
LOTUS_RUNNER_ARCH: ${{ runner.arch }}
LOTUS_PYTHON_VERSION: ${{ steps.python.outputs.python-version }}
run: |
python standards/lotus-family/conformance/lotus_family_ci_observation.py \
--repository "$GITHUB_REPOSITORY" \
--ref "$LOTUS_REF" \
--commit-sha "$LOTUS_COMMIT_SHA" \
--workflow "$GITHUB_WORKFLOW" \
--workflow-run-id "$GITHUB_RUN_ID" \
--workflow-run-attempt "$GITHUB_RUN_ATTEMPT" \
--job "$GITHUB_JOB" \
--step "Run Lotus Family conformance suite" \
--command "python -m unittest discover -s standards/lotus-family/conformance -p 'test_*.py' -v" \
--test-target "standards/lotus-family/conformance/test_*.py" \
--conclusion "$LOTUS_CONCLUSION" \
--runner-os "$LOTUS_RUNNER_OS" \
--runner-arch "$LOTUS_RUNNER_ARCH" \
--python-version "$LOTUS_PYTHON_VERSION" \
--output artifacts/lotus-ci-memory/ci-causal-observation-v0.1.json

- name: Upload immutable CI causal observation
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: lotus-ci-causal-observation-${{ github.run_id }}-${{ github.run_attempt }}
path: artifacts/lotus-ci-memory/ci-causal-observation-v0.1.json
if-no-files-found: error
retention-days: 30
92 changes: 92 additions & 0 deletions standards/lotus-family/ci-memory/SCHEMA.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# CI Causal Memory v0.1

CI Causal Memory records one immutable observation for each Lotus Family conformance run. It connects execution space and run time without allowing learned state to modify protected CI.

## Safety boundary

The observation layer is advisory and append-only.

It may:

- record exact run identity and execution location;
- normalize a stable failure signature;
- link later observations to prior runs;
- support human-reviewed regression proposals.

It may not:

- rewrite workflows, tests, policies, or protected branches;
- approve, merge, deploy, deliver, or close findings;
- mark a causal hypothesis confirmed from correlation alone;
- store secrets, raw environment values, or unbounded logs.

`PASS != APPROVED != MERGED`.

## Spacetime coordinates

Every observation has a stable spatial path:

```text
repository
→ ref
→ exact commit
→ workflow
→ job
→ step
→ command/test target
```

Every observation also has a temporal identity:

```text
workflow run ID
→ run attempt
→ observed timestamp
→ optional predecessor observation
```

## Causal states

The first slice supports these deterministic learning states:

- `observed_once`
- `repeated`
- `reproduced`
- `fix_correlated`
- `fix_validated`
- `regression_protected`

A single CI run always starts at `observed_once`. Promotion requires a separate trusted aggregator and explicit evidence.

## Failure signature

For non-success conclusions, the emitter computes SHA-256 over a canonical tuple:

```text
schema version
repository
workflow
job
step
command
conclusion
reason code
```

The signature deliberately excludes timestamps, run IDs, secrets, and raw logs so equivalent failures can be linked across runs.

## Artifact

The workflow writes:

```text
artifacts/lotus-ci-memory/ci-causal-observation-v0.1.json
```

The artifact is uploaded with `if: always()` after the conformance step. The conformance step remains failure-gating; artifact generation cannot turn a failed test into a successful job.

## Trust model

The PR workflow can emit only its own immutable observation artifact. Durable cross-run aggregation belongs in a later default-branch `workflow_run` workflow that does not execute PR code.

The initial artifact may contain caller/platform claims for repository, ref, and commit. Trusted repository/tree binding remains the responsibility of Lotus Family v0.2 materialization.
138 changes: 138 additions & 0 deletions standards/lotus-family/ci-memory/ci-causal-memory-graph-v0.1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
{
"schema_version": "lotus.ci_causal_memory_graph.v0.1",
"graph_id": "ci-causal-memory-v0.1",
"model_kind": "causal_spacetime_learning_advisory",
"dimensions": {
"spatial": "Where an observation sits in repository, commit, workflow, job, step, command, test, and artifact topology",
"temporal": "How immutable runs precede, supersede, repeat, validate, or stale prior evidence",
"causal": "How observations support hypotheses, fixes, validations, and regression guards without equating correlation with cause",
"hierarchy": "How evidence, learning state, proposals, and human authority remain separated"
},
"node_columns": [
"id",
"type",
"space",
"time",
"authority"
],
"nodes": [
["space.repository", "location", "repository", "stable", "none"],
["space.ref", "location", "ref", "run", "none"],
["space.commit", "location", "commit", "run", "none"],
["space.workflow", "location", "workflow", "run", "none"],
["space.job", "location", "job", "run", "none"],
["space.step", "location", "step", "run", "none"],
["space.command", "location", "command", "run", "none"],
["space.test_target", "location", "test", "run", "none"],
["evidence.observation", "evidence", "artifact", "run", "advisory"],
["evidence.failure_signature", "evidence", "memory", "cross_run", "advisory"],
["time.prior_observation", "temporal", "memory", "prior", "none"],
["time.current_observation", "temporal", "memory", "current", "none"],
["time.evidence_stale", "temporal", "memory", "superseded", "none"],
["memory.observed_once", "learning_state", "memory", "current", "advisory"],
["memory.pattern_repeated", "learning_state", "memory", "cross_run", "advisory"],
["cause.hypothesis", "causal_state", "memory", "cross_run", "advisory"],
["cause.confirmed", "causal_state", "memory", "validated", "human_required"],
["fix.applied", "change", "commit", "later", "human"],
["fix.validated", "validation", "run", "later", "advisory"],
["guard.regression_added", "guard", "test", "later", "human"],
["memory.proposal_created", "proposal", "issue_or_draft_pr", "later", "human_required"],
["authority.human_acceptance_required", "boundary", "governance", "always", "human"]
],
"edge_columns": [
"id",
"source",
"target",
"relation",
"dimension"
],
"edges": [
["M01", "space.repository", "space.ref", "contains", "spatial"],
["M02", "space.ref", "space.commit", "resolves_to_claim", "spatial"],
["M03", "space.commit", "space.workflow", "evaluated_by", "spatial"],
["M04", "space.workflow", "space.job", "contains", "spatial"],
["M05", "space.job", "space.step", "contains", "spatial"],
["M06", "space.step", "space.command", "executes", "spatial"],
["M07", "space.command", "space.test_target", "tests", "spatial"],
["M08", "space.test_target", "evidence.observation", "observed_at", "spatial"],
["M09", "time.prior_observation", "time.current_observation", "preceded_by", "temporal"],
["M10", "time.current_observation", "evidence.observation", "materializes", "temporal"],
["M11", "evidence.observation", "evidence.failure_signature", "normalizes_to", "causal"],
["M12", "evidence.failure_signature", "memory.observed_once", "first_seen_as", "temporal"],
["M13", "evidence.failure_signature", "memory.pattern_repeated", "recurred_as", "temporal"],
["M14", "memory.observed_once", "cause.hypothesis", "may_support", "causal"],
["M15", "memory.pattern_repeated", "cause.hypothesis", "strengthens_without_confirming", "causal"],
["M16", "cause.hypothesis", "cause.confirmed", "requires_reproduction_and_validation", "causal"],
["M17", "cause.confirmed", "fix.applied", "mitigated_by", "causal"],
["M18", "fix.applied", "fix.validated", "validated_by_later_run", "temporal"],
["M19", "fix.validated", "guard.regression_added", "protected_by", "causal"],
["M20", "memory.pattern_repeated", "memory.proposal_created", "proposes_regression", "causal"],
["M21", "memory.proposal_created", "authority.human_acceptance_required", "requires", "hierarchy"],
["M22", "cause.confirmed", "authority.human_acceptance_required", "requires", "hierarchy"],
["M23", "guard.regression_added", "authority.human_acceptance_required", "requires", "hierarchy"],
["M24", "time.evidence_stale", "cause.hypothesis", "invalidates_automatic_reuse", "temporal"],
["M25", "cause.hypothesis", "authority.human_acceptance_required", "requires_before_action", "hierarchy"]
],
"trajectories": [
{
"id": "new-failure",
"path": [
"space.repository",
"space.ref",
"space.commit",
"space.workflow",
"space.job",
"space.step",
"space.command",
"space.test_target",
"evidence.observation",
"evidence.failure_signature",
"memory.observed_once",
"cause.hypothesis",
"authority.human_acceptance_required"
],
"outcome": "advisory_investigation"
},
{
"id": "recurrence",
"path": [
"time.prior_observation",
"time.current_observation",
"evidence.observation",
"evidence.failure_signature",
"memory.pattern_repeated",
"memory.proposal_created",
"authority.human_acceptance_required"
],
"outcome": "advisory_regression_proposal"
},
{
"id": "validated-fix",
"path": [
"cause.hypothesis",
"cause.confirmed",
"fix.applied",
"fix.validated",
"guard.regression_added",
"authority.human_acceptance_required"
],
"outcome": "human_reviewed_durable_guard"
},
{
"id": "stale-learning",
"path": [
"time.evidence_stale",
"cause.hypothesis",
"authority.human_acceptance_required"
],
"outcome": "no_automatic_reuse"
}
],
"invariants": {
"correlation_is_not_confirmation": true,
"single_run_cause_state": "unconfirmed",
"automatic_mutation_allowed": false,
"human_acceptance_required": true,
"pass_is_not_approval_or_merge": true
}
}
Loading
Loading