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
224 changes: 224 additions & 0 deletions .github/workflows/rll-authorial-science-fabric-v1.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
name: RLL Authorial Science Fabric V1

"on":
pull_request:
branches:
- rll/lab
paths:
- "services/authorial_fabric/**"
- "tools/rll_authorial_ingress.py"
- "tests/test_rll_authorial_ingress.py"
- "tests/test_rll_capability_secret_router.py"
- "data/governance/RLL_CAPABILITY_SECRET_ROUTER_V1.json"
- ".github/workflows/rll-authorial-science-fabric-v1.yml"
workflow_dispatch:
inputs:
manifest:
description: "Manifest under services/authorial_fabric/manifests/"
required: true
default: "services/authorial_fabric/manifests/voynich_geometry.discovery.v1.json"
type: string
credential_profile:
description: "Optional bounded GitHub read credential profile"
required: true
default: none
type: choice
options:
- none
- pat_actions
- pat_agents
- pat_env
- pat_environments
allow_unpinned:
description: "Discovery only: permit TOKEN_VAZIO expected hash; result is OBSERVED_UNPINNED, never PASS_PINNED"
required: true
default: false
type: boolean

permissions:
contents: read

concurrency:
group: rll-authorial-science-fabric-${{ github.ref }}
cancel-in-progress: false

jobs:
contract:
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- name: Checkout exact source
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Audit bundled discovery manifest
run: |
set -euo pipefail
mkdir -p artifacts/authorial-fabric-contract
python3 tools/rll_authorial_ingress.py audit \
services/authorial_fabric/manifests/voynich_geometry.discovery.v1.json \
| tee artifacts/authorial-fabric-contract/manifest-audit.json

- name: Execute stdlib falsifiers
run: |
set -euo pipefail
{
python3 tests/test_rll_authorial_ingress.py -v
python3 tests/test_rll_capability_secret_router.py -v
} 2>&1 | tee artifacts/authorial-fabric-contract/unittest.log

- name: Validate fabric JSON contracts
run: |
set -euo pipefail
python3 - <<'PY' | tee artifacts/authorial-fabric-contract/contract-check.json
import json
from pathlib import Path

fabric = json.loads(Path('services/authorial_fabric/fabric.v1.json').read_text())
policy = json.loads(Path('data/governance/RLL_CAPABILITY_SECRET_ROUTER_V1.json').read_text())
assert fabric['schema'] == 'rll.authorial_fabric.v1'
assert fabric['claim_allowed'] is False
assert policy['schema'] == 'rll.capability_secret_router.v1'
assert policy['claim_allowed'] is False
assert policy['workflow_boundary']['write_authority'] == 'NONE_IN_V1'
assert policy['workflow_boundary']['delete_authority'] == 'FORBIDDEN'
assert policy['same_value_across_names'] == 'TOKEN_VAZIO_EXTERNAL_SETTING_NOT_TESTED'
lanes = {item['id']: item for item in fabric['lanes']}
assert lanes['freestanding_native']['class'] == 'EXECUTION_CORE'
for adapter in ['science_ingress', 'github_actions', 'android_ndk', 'jni_bridge', 'android_sdk_buildtools', 'r8_dex_optimizer', 'art_jit_aot', 'python_factory']:
assert lanes[adapter]['runtime_dependency'] is False
print(json.dumps({'decision': 'PASS_STATIC', 'claim_allowed': False, 'lane_count': len(lanes)}, indent=2))
PY

- name: Upload contract evidence
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: rll-authorial-fabric-contract-${{ github.run_id }}
path: artifacts/authorial-fabric-contract/
retention-days: 14
if-no-files-found: error

acquire:
if: ${{ github.event_name == 'workflow_dispatch' }}
needs: contract
runs-on: ubuntu-24.04
timeout-minutes: 20
env:
MANIFEST: ${{ inputs.manifest }}
ALLOW_UNPINNED: ${{ inputs.allow_unpinned }}
RUN_DIR: artifacts/authorial-fabric-network
steps:
- name: Checkout exact source
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Bound manifest path and initialize receipt area
run: |
set -euo pipefail
case "$MANIFEST" in
services/authorial_fabric/manifests/*.json) ;;
*) echo "manifest must remain under services/authorial_fabric/manifests/" >&2; exit 2 ;;
esac
test -f "$MANIFEST"
mkdir -p "$RUN_DIR/downloads" "$RUN_DIR/receipts"
printf '%s\n' "${GITHUB_SHA}" > "$RUN_DIR/source-head.txt"
printf '%s\n' "${{ inputs.credential_profile }}" > "$RUN_DIR/credential-profile.txt"

- name: Materialize public HTTPS sources
if: ${{ inputs.credential_profile == 'none' }}
run: |
set -euo pipefail
EXTRA=""
if [ "$ALLOW_UNPINNED" = "true" ]; then EXTRA="--allow-unpinned"; fi
python3 tools/rll_authorial_ingress.py materialize "$MANIFEST" \
--out "$RUN_DIR/downloads" \
--receipt "$RUN_DIR/receipts/network-receipt.json" \
--credential-profile none $EXTRA

- name: Materialize with PAT_ACTIONS
if: ${{ inputs.credential_profile == 'pat_actions' }}
env:
CAPABILITY_PAT: ${{ secrets.PAT_ACTIONS }}
run: |
set -euo pipefail
if [ -z "$CAPABILITY_PAT" ]; then
printf '%s\n' '{"decision":"FAIL_CLOSED","gap":"TOKEN_VAZIO_PAT_ACTIONS_RUNTIME_BINDING","claim_allowed":false}' > "$RUN_DIR/receipts/network-receipt.json"
exit 4
fi
EXTRA=""; if [ "$ALLOW_UNPINNED" = "true" ]; then EXTRA="--allow-unpinned"; fi
export RLL_INGRESS_TOKEN="$CAPABILITY_PAT"
python3 tools/rll_authorial_ingress.py materialize "$MANIFEST" --out "$RUN_DIR/downloads" --receipt "$RUN_DIR/receipts/network-receipt.json" --credential-profile pat_actions $EXTRA
unset RLL_INGRESS_TOKEN CAPABILITY_PAT

- name: Materialize with PAT_AGENTS
if: ${{ inputs.credential_profile == 'pat_agents' }}
env:
CAPABILITY_PAT: ${{ secrets.PAT_AGENTS }}
run: |
set -euo pipefail
if [ -z "$CAPABILITY_PAT" ]; then
printf '%s\n' '{"decision":"FAIL_CLOSED","gap":"TOKEN_VAZIO_PAT_AGENTS_RUNTIME_BINDING","claim_allowed":false}' > "$RUN_DIR/receipts/network-receipt.json"
exit 4
fi
EXTRA=""; if [ "$ALLOW_UNPINNED" = "true" ]; then EXTRA="--allow-unpinned"; fi
export RLL_INGRESS_TOKEN="$CAPABILITY_PAT"
python3 tools/rll_authorial_ingress.py materialize "$MANIFEST" --out "$RUN_DIR/downloads" --receipt "$RUN_DIR/receipts/network-receipt.json" --credential-profile pat_agents $EXTRA
unset RLL_INGRESS_TOKEN CAPABILITY_PAT

- name: Materialize with PAT_ENV
if: ${{ inputs.credential_profile == 'pat_env' }}
env:
CAPABILITY_PAT: ${{ secrets.PAT_ENV }}
run: |
set -euo pipefail
if [ -z "$CAPABILITY_PAT" ]; then
printf '%s\n' '{"decision":"FAIL_CLOSED","gap":"TOKEN_VAZIO_PAT_ENV_RUNTIME_BINDING","claim_allowed":false}' > "$RUN_DIR/receipts/network-receipt.json"
exit 4
fi
EXTRA=""; if [ "$ALLOW_UNPINNED" = "true" ]; then EXTRA="--allow-unpinned"; fi
export RLL_INGRESS_TOKEN="$CAPABILITY_PAT"
python3 tools/rll_authorial_ingress.py materialize "$MANIFEST" --out "$RUN_DIR/downloads" --receipt "$RUN_DIR/receipts/network-receipt.json" --credential-profile pat_env $EXTRA
unset RLL_INGRESS_TOKEN CAPABILITY_PAT

- name: Materialize with PAT_ENVIRONMENTS and legacy typo fallback
if: ${{ inputs.credential_profile == 'pat_environments' }}
env:
CAPABILITY_PAT_CANONICAL: ${{ secrets.PAT_ENVIRONMENTS }}
CAPABILITY_PAT_LEGACY: ${{ secrets.PAT_ENVIOREMENTS }}
run: |
set -euo pipefail
CAPABILITY_PAT="$CAPABILITY_PAT_CANONICAL"
if [ -z "$CAPABILITY_PAT" ]; then CAPABILITY_PAT="$CAPABILITY_PAT_LEGACY"; fi
if [ -z "$CAPABILITY_PAT" ]; then
printf '%s\n' '{"decision":"FAIL_CLOSED","gap":"TOKEN_VAZIO_PAT_ENVIRONMENTS_RUNTIME_BINDING","claim_allowed":false}' > "$RUN_DIR/receipts/network-receipt.json"
exit 4
fi
EXTRA=""; if [ "$ALLOW_UNPINNED" = "true" ]; then EXTRA="--allow-unpinned"; fi
export RLL_INGRESS_TOKEN="$CAPABILITY_PAT"
python3 tools/rll_authorial_ingress.py materialize "$MANIFEST" --out "$RUN_DIR/downloads" --receipt "$RUN_DIR/receipts/network-receipt.json" --credential-profile pat_environments $EXTRA
unset RLL_INGRESS_TOKEN CAPABILITY_PAT CAPABILITY_PAT_CANONICAL CAPABILITY_PAT_LEGACY

- name: Build artifact hash inventory
if: always()
run: |
set -euo pipefail
TMP_SUMS="$RUN_DIR/receipts/.SHA256SUMS.tmp"
find "$RUN_DIR" -type f \
! -name 'SHA256SUMS.txt' \
! -name '.SHA256SUMS.tmp' \
-print0 \
| sort -z \
| xargs -0 -r sha256sum > "$TMP_SUMS"
mv "$TMP_SUMS" "$RUN_DIR/receipts/SHA256SUMS.txt"

- name: Upload source custody bundle
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: rll-authorial-science-ingress-${{ github.run_id }}
path: artifacts/authorial-fabric-network/
retention-days: 14
if-no-files-found: error
103 changes: 103 additions & 0 deletions data/governance/RLL_CAPABILITY_SECRET_ROUTER_V1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
{
"schema": "rll.capability_secret_router.v1",
"version": "1.0.0",
"date": "2026-10-05",
"canonical_repository": "instituto-Rafael/relativity-living-light",
"relationship_to_credential_authority": "SUPPLEMENTAL_OWNER_DECLARED_CAPABILITY_SURFACE; DOES_NOT_REPLACE_RLL_CREDENTIAL_AUTHORITY_POLICY_V1",
"claim_allowed": false,
"publication_effect": "NONE",
"secret_values_must_never_enter_repository": true,
"secret_values_must_never_enter_receipts": true,
"secret_values_must_never_be_hashed_for_COMPARISON": true,
"same_value_across_names": "TOKEN_VAZIO_EXTERNAL_SETTING_NOT_TESTED",
"profiles": {
"pat_actions": {
"canonical_secret_name": "PAT_ACTIONS",
"legacy_aliases": [],
"purpose": "manual GitHub read/acquisition capability for Actions-scoped source custody",
"runtime_presence": "TOKEN_VAZIO_UNTIL_MANUAL_DISPATCH"
},
"pat_agents": {
"canonical_secret_name": "PAT_AGENTS",
"legacy_aliases": [],
"purpose": "manual GitHub read/acquisition capability for agent-scoped source custody",
"runtime_presence": "TOKEN_VAZIO_UNTIL_MANUAL_DISPATCH"
},
"pat_env": {
"canonical_secret_name": "PAT_ENV",
"legacy_aliases": [],
"purpose": "manual environment-scoped GitHub read/acquisition capability",
"runtime_presence": "TOKEN_VAZIO_UNTIL_MANUAL_DISPATCH"
},
"pat_environments": {
"canonical_secret_name": "PAT_ENVIRONMENTS",
"legacy_aliases": [
"PAT_ENVIOREMENTS"
],
"purpose": "manual environments-scoped GitHub read/acquisition capability",
"runtime_presence": "TOKEN_VAZIO_UNTIL_MANUAL_DISPATCH",
"legacy_alias_policy": "canonical name wins; typo alias is fallback only and must never be copied into repository content"
}
},
"workflow_boundary": {
"allowed_workflow": ".github/workflows/rll-authorial-science-fabric-v1.yml",
"allowed_event_for_secret_consumption": "workflow_dispatch_only",
"repository_permissions": {
"contents": "read"
},
"allowed_remote_http_methods": [
"GET"
],
"credentialed_host": "api.github.com",
"credentialed_path_family": "/repos/{owner}/{repo}/contents/{path}",
"cross_repository_scope": "TOKEN_VAZIO_EXTERNAL_PAT_SETTING",
"write_authority": "NONE_IN_V1",
"delete_authority": "FORBIDDEN",
"force_push": "FORBIDDEN",
"git_ref_delete": "FORBIDDEN",
"shell_trace": "FORBIDDEN",
"environment_dump": "FORBIDDEN"
},
"receipt_boundary": {
"allowed_fields": [
"credential_profile",
"credential_present_boolean",
"source_url",
"artifact_sha256",
"artifact_bytes",
"authority",
"license_state",
"decision",
"residuals"
],
"forbidden_fields": [
"secret_value",
"secret_length",
"secret_hash",
"authorization_header",
"value_equivalence_between_secret_names"
]
},
"invariants": [
"SOURCE != ARTIFACT != EXECUTION != EVIDENCE != CLAIM",
"TOKEN_VAZIO != 0",
"IMPLEMENTED_UNTESTED != PASS",
"PAT possession != repository authority",
"PAT possession != scientific evidence",
"hosted CI != freestanding runtime",
"Android NDK/JNI/SDK/R8/ART are factory or adapter surfaces, not freestanding runtime dependencies"
],
"f_ok": [
"canonical spelling PAT_ENVIRONMENTS established",
"legacy PAT_ENVIOREMENTS retained only as a non-persisted fallback binding",
"all four requested capability profiles are explicitly typed",
"V1 remote authority is read-only and delete-free"
],
"f_gap": [
"runtime presence of each secret",
"fine-grained PAT repository scopes and intrinsic permissions",
"whether different secret names contain the same PAT value",
"cross-repository provider enforcement"
],
"f_next": "Run only the manual acquisition workflow for a manifest that needs a credentialed GitHub contents source; record presence boolean and source/artifact receipt without reading or comparing secret material."
}
65 changes: 65 additions & 0 deletions services/authorial_fabric/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# RLL Authorial Science Fabric V1

Status: `IMPLEMENTED_UNTESTED_CI` · `claim_allowed=false`

This directory gives RLL one low-friction service boundary for scientific source custody, build/measurement adapters and the existing freestanding core.

## Separation that must not collapse

```text
SOURCE -> ARTIFACT -> EXECUTION -> EVIDENCE -> CLAIM
|
+-> factory/adapters: Python stdlib, CI, NDK, JNI, SDK, R8, ART/JIT
|
+-> never a runtime dependency of the freestanding ELF
```

The canonical freestanding computation remains under `core/lowlevel_runtime`. This fabric does not replace it and does not relabel Android userspace as bare metal.

## Directory contract

- `fabric.v1.json` — typed registry of execution/factory/evidence lanes.
- `manifests/` — source manifests. URLs, authority, rights state, byte bounds and expected SHA-256 live here.
- `tools/rll_authorial_ingress.py` — stdlib-only acquisition/custody tool.
- `.github/workflows/rll-authorial-science-fabric-v1.yml` — CI static gate plus manual network materialization.
- `data/governance/RLL_CAPABILITY_SECRET_ROUTER_V1.json` — bounded PAT aliases and non-destructive rules.

Downloaded PDFs, images and datasets are not committed automatically. A manual acquisition run writes them to an ephemeral CI directory and publishes a GitHub Actions artifact together with a receipt. A hash learned for a previously unpinned source is `OBSERVED_UNPINNED`, not `PASS_PINNED`; promotion requires a reviewed successor manifest.

## Credential profiles

Canonical profiles are:

- `PAT_ACTIONS` -> `pat_actions`
- `PAT_AGENTS` -> `pat_agents`
- `PAT_ENV` -> `pat_env`
- `PAT_ENVIRONMENTS` -> `pat_environments`

`PAT_ENVIOREMENTS` is retained only as a legacy typo fallback for the last profile. Secret values are never printed, stored, hashed or compared. Whether these names contain the same PAT value is provider-side state and remains `TOKEN_VAZIO` here.

V1 credentialed acquisition is deliberately narrower than the PAT's possible provider permissions: **GET-only GitHub Contents API**. No push, POST, PUT, PATCH, DELETE, ref deletion or force-push is implemented.

## Internet/source model

Public HTTPS sources need no PAT. Credential profiles are for private/cross-repository GitHub source custody only. Each materialized byte stream gets SHA-256, byte count, authority and rights state in the receipt.

For dynamic/unpinned public sources, use `--allow-unpinned` only for discovery. The next reviewed delta should pin the observed digest if the source is appropriate and legally usable.

## Voynich seed

`manifests/voynich_geometry.discovery.v1.json` starts the angular/graph experiment from the Beinecke MS 408 catalog record. It intentionally does **not** claim a high-resolution image endpoint, image rights, folio hashes or a decipherment. Those unresolved items remain `TOKEN_VAZIO` until resolved from the primary collection source.

## Freestanding meaning

`freestanding_native` means the execution core can be built and run without libc, heap allocation, Python/JVM/Android runtime and external native libraries. Compiler/linker/CI are factory tools, not runtime dependencies. NDK/JNI/SDK/R8/ART lanes may benchmark or bridge the same mathematics but do not redefine the core.

## Success criterion V1

1. static manifest audit PASS;
2. stdlib unit tests PASS;
3. credential-bearing jobs manual-only and non-destructive;
4. manual materialization emits artifact + receipt without secret material;
5. pinned source bytes must match SHA-256 exactly;
6. scientific claims remain disabled until a separate evidence gate exists.

Rollback: close/revert only this feature branch/PR. No history rewrite and no deletion of prior receipts.
Loading
Loading