Record native security preparation and owner checkpoints (6/7)
This commit is contained in:
parent
ae055669d0
commit
a6d0e1ea3d
18 changed files with 2334 additions and 0 deletions
|
|
@ -0,0 +1,153 @@
|
|||
{
|
||||
"ok": true,
|
||||
"status": "applied",
|
||||
"repo_slug": "secrets-engine",
|
||||
"commit": "691dc742362eeec45d5bd32d2b468f31a959748e",
|
||||
"requests": 2,
|
||||
"elapsed_ms": 5412.9,
|
||||
"git": {
|
||||
"upstream": "origin/main",
|
||||
"behind": 0,
|
||||
"ahead": 0
|
||||
},
|
||||
"identifiers": {
|
||||
"schema": "repo-manager.identifier-assignment.v1",
|
||||
"ok": true,
|
||||
"executed": true,
|
||||
"repo": "secrets-engine",
|
||||
"namespace": "helixforge",
|
||||
"assignments": [],
|
||||
"historical_invalid_identifiers": [],
|
||||
"historical_identity_collisions": [],
|
||||
"files_changed": []
|
||||
},
|
||||
"receipt": {
|
||||
"schema": "state-hub.repository-projection-reconcile.v1",
|
||||
"instance_role": "primary",
|
||||
"instance_label": "railiance01",
|
||||
"expected_commit": "691dc742362eeec45d5bd32d2b468f31a959748e",
|
||||
"derived_commit": "691dc742362eeec45d5bd32d2b468f31a959748e",
|
||||
"outcome": {
|
||||
"schema": "state-hub.projection-reset.v1",
|
||||
"repo_slug": "secrets-engine",
|
||||
"commit": "691dc742362eeec45d5bd32d2b468f31a959748e",
|
||||
"status": "applied",
|
||||
"counts": {
|
||||
"created": 0,
|
||||
"updated": 17,
|
||||
"retired": 0,
|
||||
"refused": 0,
|
||||
"released": 0,
|
||||
"created_tasks": 0,
|
||||
"updated_tasks": 0,
|
||||
"cancelled_tasks": 0,
|
||||
"created_edges": 0,
|
||||
"removed_edges": 0,
|
||||
"unresolved_edges": 0,
|
||||
"external_edges": 7
|
||||
},
|
||||
"created": [],
|
||||
"updated": [
|
||||
"SECRETS-WP-0001",
|
||||
"SECRETS-WP-0002",
|
||||
"SECRETS-WP-0003",
|
||||
"SECRETS-WP-0004",
|
||||
"SECRETS-WP-0005",
|
||||
"SECRETS-WP-0006",
|
||||
"SECRETS-WP-0007",
|
||||
"SECRETS-WP-0008",
|
||||
"SECRETS-WP-0009",
|
||||
"SECRETS-WP-0010",
|
||||
"SECRETS-WP-0011",
|
||||
"SECRETS-WP-0012",
|
||||
"SECRETS-WP-0013",
|
||||
"SECRETS-WP-0014",
|
||||
"SECRETS-WP-0015",
|
||||
"SECRETS-WP-ADHOC-2026-08-21",
|
||||
"SECRETS-WP-ADHOC-2026-08-23"
|
||||
],
|
||||
"retired": [],
|
||||
"released": [],
|
||||
"created_tasks": [],
|
||||
"updated_tasks": [],
|
||||
"cancelled_tasks": [],
|
||||
"created_edges": [],
|
||||
"removed_edges": [],
|
||||
"unresolved_edges": [],
|
||||
"external_edges": [
|
||||
{
|
||||
"workplan": "SECRETS-WP-0006",
|
||||
"from": "SECRETS-WP-0006-T06",
|
||||
"target": "SECRETS-WP-0006-T05",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "31f7f8ea-7f73-516c-8877-f03a13f1db82",
|
||||
"from_task_id": "1431edae-5791-5892-8c4b-829419b537d2",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "fb103f1e-2ff7-5de5-9a2c-191a19c43542"
|
||||
},
|
||||
{
|
||||
"workplan": "SECRETS-WP-0013",
|
||||
"from": "SECRETS-WP-0013-T03",
|
||||
"target": "RPF-WP-0035-T12",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "5e38aecc-85ca-5f55-94c6-9fbb08604819",
|
||||
"from_task_id": "5f8f7c41-5921-543f-a7c6-0b1350ea6d82",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "914bf383-c13f-5247-9af0-91d7e3a4784a"
|
||||
},
|
||||
{
|
||||
"workplan": "SECRETS-WP-0013",
|
||||
"from": "SECRETS-WP-0013-T03",
|
||||
"target": "SECRETS-WP-0013-T01",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "5e38aecc-85ca-5f55-94c6-9fbb08604819",
|
||||
"from_task_id": "5f8f7c41-5921-543f-a7c6-0b1350ea6d82",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "b2f0d462-a542-518b-a26b-b7ec07b3c7c1"
|
||||
},
|
||||
{
|
||||
"workplan": "SECRETS-WP-0007",
|
||||
"from": "SECRETS-WP-0007-T07",
|
||||
"target": "SECRETS-WP-0006-T06",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "68a39be1-bd9c-5133-ad64-e7bca892aaf3",
|
||||
"from_task_id": "a0a1dd92-d703-5a95-b488-d895f34d5cf7",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "1431edae-5791-5892-8c4b-829419b537d2"
|
||||
},
|
||||
{
|
||||
"workplan": "SECRETS-WP-0007",
|
||||
"from": "SECRETS-WP-0007-T07",
|
||||
"target": "SECRETS-WP-0006-T05",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "68a39be1-bd9c-5133-ad64-e7bca892aaf3",
|
||||
"from_task_id": "a0a1dd92-d703-5a95-b488-d895f34d5cf7",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "fb103f1e-2ff7-5de5-9a2c-191a19c43542"
|
||||
},
|
||||
{
|
||||
"workplan": "SECRETS-WP-0014",
|
||||
"from": "SECRETS-WP-0014-T03",
|
||||
"target": "SECRETS-WP-0014-T02",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "7252469d-d7a5-5c18-8911-b511b8c6a736",
|
||||
"from_task_id": "85aa4c78-b66d-5201-8e31-0ed50e7eaeec",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "877782e5-045b-5186-8b95-82e25db21a5a"
|
||||
},
|
||||
{
|
||||
"workplan": "SECRETS-WP-0008",
|
||||
"from": "SECRETS-WP-0008-T06",
|
||||
"target": "RPF-WP-0035-T02",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "9c9e5164-b2f5-5ea2-a557-5368d65e9fe0",
|
||||
"from_task_id": "d7bc8bdc-a0f8-5058-a640-374ef9859148",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "e0c82ea9-05a5-537e-8fbf-67534263572e"
|
||||
}
|
||||
],
|
||||
"refused": [],
|
||||
"notes": []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"owner": "secrets-engine",
|
||||
"base_revision": "c59bbf568c0be8a72ac593508f48c9b1f61ec4c1",
|
||||
"files": {
|
||||
"docs/keycape-isolated-consumer-continuity-plan.md": "sha256:b984425e043e08e5bd1e53dbef90839af5258b8fdeee057d2293a93b78bb492d",
|
||||
"workplans/SECRETS-WP-0015-original-keycape-recovery-selector.md": "sha256:c35019a8609e52fc4a7f5cc14e7b12cdc17dffbc8cd0b564a48a6b9fb6b5035d"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
--- a/workplans/SECRETS-WP-0015-original-keycape-recovery-selector.md
|
||||
+++ b/workplans/SECRETS-WP-0015-original-keycape-recovery-selector.md
|
||||
@@ -4,7 +4,7 @@
|
||||
title: "Prepare original KeyCape service selector and isolated consumer continuity"
|
||||
domain: infotech
|
||||
repo: secrets-engine
|
||||
-status: ready
|
||||
+status: active
|
||||
owner: codex
|
||||
topic_slug: custodian
|
||||
created: "2026-10-17"
|
||||
@@ -17,8 +17,9 @@
|
||||
|
||||
Needed source-owner work for NK-WP-0049-T36/T18. Reviewed against current
|
||||
Lifecycle INTENT, explicit consumer constants/custody source and dated historical
|
||||
-proof. Ready means work can proceed, not native assent. Finished0012 remains
|
||||
-finished; functional adoption/backend entitlement stay0008T06/0013. No new grant,
|
||||
+proof. Active records the delivered source plan and remaining native owner wait;
|
||||
+it is not native assent. Finished0012 remains finished; functional adoption/backend
|
||||
+entitlement stay0008T06/0013. No new grant,
|
||||
secret fetch, provider login, production redirect or external message occurred.
|
||||
|
||||
## Establish exact current intended source selector
|
||||
@@ -61,22 +62,37 @@
|
||||
|
||||
```task
|
||||
id: SECRETS-WP-0015-T03
|
||||
-status: todo
|
||||
+status: done
|
||||
priority: high
|
||||
assignee: codex
|
||||
state_hub_task_id: "6262a915-7655-50be-b9f7-481f816d7335"
|
||||
```
|
||||
|
||||
-Next: map the exact original archive-delivered registration and producer-native
|
||||
-checker result to the intended consumer, then prepare a source-reviewed isolated
|
||||
-proof/custody plan. Current consumer source requires attended OpenBao memory read
|
||||
-and refuses files; ordinary OpenBao/KeyCape outage is therefore a real dependency.
|
||||
-Do not add a fallback, persistent consumer copy or unreviewed injection source.
|
||||
-Clarify which continuity claim can be proved offline and which requires an exact
|
||||
-accepted owner custody/provider path. Bind current original selectors, image/
|
||||
-source/TLS metadata, negative cases, timeout/abort and cleanup; retain protected
|
||||
-backend operation entitlement in existing0008/0013. Done when that exact plan and
|
||||
-remaining owner dependencies are reviewable, without retrieving any value.
|
||||
+Completed 2026-10-17 as source-plan preparation only. The reviewed owner plan
|
||||
+is [keycape-isolated-consumer-continuity-plan.md](../docs/keycape-isolated-consumer-continuity-plan.md),
|
||||
+bound to the frozen Custodian `consumer-outage-r1` packet. It distinguishes the
|
||||
+restored original issuer check, exact Secrets consumer claim compatibility and
|
||||
+actual original OpenBao consumer continuity, preserving the no-file/no-fallback
|
||||
+client-secret source contract. Offline founder authority, original TLS/private
|
||||
+admission, exact source/runtime/receipt interfaces, positive/negative/equality
|
||||
+oracles, timeout, abort and cleanup requirements are reviewable. The plan's done
|
||||
+criterion is met; no native or private custody dependency is represented as done.
|
||||
+
|
||||
+The packet includes an unexecuted-on-real-input one-shot claim observer candidate;
|
||||
+it is not wired into recovery or ordinary service authentication. Five synthetic
|
||||
+tests pass, including seven explicitly noncryptographic claim-parser negatives
|
||||
+and source/input refusal checks. The existing exact-source selector preflight
|
||||
+passes. These source checks establish neither token signature/native provenance
|
||||
+nor client-secret acquisition, OpenBao login, backend entitlement or downstream
|
||||
+reconnect. No private archive, original token/key, OpenBao endpoint or native
|
||||
+approval was accessed. Source integration/publication/projection are separate
|
||||
+coordinator follow-through; the immutable packet retains source hashes and limits.
|
||||
+
|
||||
+Remaining actual owner dependencies are explicit in the plan and T04: NK49T33
|
||||
+complete original TLS/archive/private admission; an independently recovered
|
||||
+original OpenBao and its custody/OIDC/MFA graph for full consumer continuity;
|
||||
+exact native action approval and resource-server negative/revocation receipts.
|
||||
+Protected backend operation entitlement stays in existing0008T06/0013.
|
||||
|
||||
## Verify the separately admitted actual isolated consumer result
|
||||
|
||||
@@ -87,7 +103,7 @@
|
||||
assignee: codex
|
||||
needs_human: true
|
||||
depends_on: [SECRETS-WP-0015-T03, NK-WP-0049-T33]
|
||||
-blocking_reason: "Await exact consumer proof/custody plan plus original TLS/private admission readiness; actual attended owner path/authority remains required."
|
||||
+blocking_reason: "Source plan delivered in T03. Await NK-WP-0049-T33 original TLS/archive/private admission, exact native owner authority, and original OpenBao/custody recovery for actual consumer continuity."
|
||||
state_hub_task_id: "aeec6eb0-39e2-5f7c-8f5d-778133edfc73"
|
||||
```
|
||||
|
||||
--- /dev/null
|
||||
+++ b/docs/keycape-isolated-consumer-continuity-plan.md
|
||||
@@ -0,0 +1,99 @@
|
||||
+# Original KeyCape isolated consumer continuity plan
|
||||
+
|
||||
+Owner: secrets-engine. Source outcome: SECRETS-WP-0015-T03, 2026-10-17.
|
||||
+This is a reviewed source plan, not native assent, a custody grant or an
|
||||
+executed recovery. T04 remains a human wait on the complete NK49T33 attempt.
|
||||
+
|
||||
+The [frozen owner packet](../../the-custodian/docs/changes/netkingdom-target-2026-10-17/consumer-outage-r1/OWNER-PLAN.md)
|
||||
+contains the exact custody/command/negative/equality/timeout/abort plan and source
|
||||
+references. Its owner-plan SHA-256 is
|
||||
+`sha256:d358aaeedc18c42c591d3301ec34f493e63bf579bf5a17b6ccc7e32ec88ea8ed`.
|
||||
+The packet remains immutable; this source note does not revise its authority.
|
||||
+
|
||||
+## Exact original selector and source
|
||||
+
|
||||
+Use the existing [public selector](keycape-recovery-selector.json): issuer
|
||||
+`https://kc.coulomb.social`, client/audience `secrets-engine-openbao`, env name
|
||||
+`KEYCAPE_SECRETS_ENGINE_OPENBAO_CLIENT_SECRET`, subject
|
||||
+`service:secrets-engine`, tenant `tenant:platform`, exactly role
|
||||
+`secrets-engine`, scope `openbao:login`, denied scope `openbao:admin`.
|
||||
+The current consumer `service_auth.py` source SHA-256 is
|
||||
+`sha256:c0ade429edf452ad17f05d690b7ebef091db7f1a42b5ac350f1e40955c8586c0`.
|
||||
+Its existing AST-only selector preflight passes at that exact hash. Historical
|
||||
+issuer/consumer successes predate the archive and retain their historical scope.
|
||||
+
|
||||
+The packet's [one-shot observer candidate](../../the-custodian/docs/changes/netkingdom-target-2026-10-17/consumer-outage-r1/consumer_contract_observer.py)
|
||||
+is `sha256:23467730be61625d53b34c09e62f737a35e3def10d22a3a64664835961d3f4bd`.
|
||||
+Its frozen four-file consumer-source manifest is
|
||||
+`sha256:5b0409d7141514295e7d0f636ff6fa5dbe9d1f0d4d23b2f9ebce84a174d69499`.
|
||||
+The observer remains a source candidate: it was tested with synthetic unsigned
|
||||
+tokens only and is not installed, invoked on real material, or wired into either
|
||||
+NK49 recovery or ordinary consumer authentication. Five synthetic tests pass;
|
||||
+seven parser-negative variants and source/input refusal checks are within those
|
||||
+tests, not extra native successes.
|
||||
+
|
||||
+## Claims and custody boundaries
|
||||
+
|
||||
+1. **Original issuer:** the existing frozen NK49 native checker binds the
|
||||
+ original archived registration/env, original TLS/trust/JWKS, wrong-secret and
|
||||
+ excess-scope refusal, and exact original config/registry/policy/receipt
|
||||
+ equality. Its receipt keeps downstream consumer reconnect false.
|
||||
+2. **Consumer claim compatibility:** after a newly reviewed NK49 source/admission
|
||||
+ closure, the existing issuer `service-token` command may mint a short-lived
|
||||
+ original-identity token in the issuer's private tmpfs. A reviewed same-session
|
||||
+ wrapper would hand only that bounded token object over private stdin to the
|
||||
+ exact Secrets claim observer, then prove transient-token/resource cleanup.
|
||||
+ The original client secret stays in the restored issuer environment. Native
|
||||
+ issuer/JWKS verification precedes consumer parsing; the observer verifies no
|
||||
+ signature or native provenance. This proposed callback is not implemented.
|
||||
+3. **Full original OpenBao consumer continuity:** requires Platform/rapp-openbao's
|
||||
+ independently recovered original backend/custody, original KV registration,
|
||||
+ narrow OIDC source role and actual operator authentication/MFA dependencies,
|
||||
+ plus exact isolated routing/trust. NK49's identity archive does not supply
|
||||
+ OpenBao Raft recovery. A fresh backend, production login or injected secret
|
||||
+ cannot substitute for this return. Then use the unchanged ordinary attended
|
||||
+ OpenBao in-memory secret source, KeyCape exchange, actual OpenBao JWT login
|
||||
+ and definite operator/engine session revocation.
|
||||
+
|
||||
+The current no-file/no-fallback direction remains. Do not inject the recovered
|
||||
+issuer secret into ordinary `login_service_jwt`, create a persistent consumer
|
||||
+copy, use ambient/bootstrap credentials, or redirect production. An exceptional
|
||||
+source would need a separate explicit owner/founder custody decision; none is
|
||||
+proposed or implemented here. Service identity/login-only policy is not protected
|
||||
+backend execution authority. SECRETS-WP-0008-T06/0013 retain those scopes;
|
||||
+finished SECRETS-WP-0012 remains finished.
|
||||
+
|
||||
+## Actual acceptance and next owner action
|
||||
+
|
||||
+The next action is to assemble NK49T33's exact owner-held original TLS/archive/
|
||||
+private-admission packet and surviving offline founder authorization before any
|
||||
+key prompt. Matching hashes, possession of an archive key, this workplan and
|
||||
+historical CCRs are not that authorization. Bind exact source/image/executor,
|
||||
+original issuer/case/target, deadline and permitted isolated effects in the
|
||||
+existing supervised recovery process. No new auth or approval service is needed.
|
||||
+
|
||||
+Keep original ciphertext/transfer/source/binary/trust and manifest-binding-mode
|
||||
+interfaces. Private manifests and equality hashes stay inside custody. Freeze any
|
||||
+new observer callback/dependency closure, native command count and phase-specific
|
||||
+negative parsing; its source/synthetic lifecycle review must precede real input.
|
||||
+Use the existing bounded NK49 execution, exact pidfd/session quiescence and
|
||||
+registered tmpfs/container cleanup. Abort on unknown provenance, changed original
|
||||
+bytes, ambiguous daemon action or incomplete cleanup; preserve failed receipts
|
||||
+and uncertainty rather than retrying or reinitializing state.
|
||||
+
|
||||
+Require an actual positive original-issuer token and exact consumer claims,
|
||||
+including no extra roles. Native wrong-expected-audience/required-role refusals
|
||||
+are verifier checks, not OpenBao authorization. The observer's seven deliberately
|
||||
+modified payloads prove parser refusal only; unsigned mutations prove no signed
|
||||
+claim denial. Full backend acceptance separately requires real resource-server
|
||||
+wrong-audience/scope/role refusal, restored policy/role/KV equality and session
|
||||
+revocation through the existing owner path. Missing original signed negative
|
||||
+cases stay missing; do not create grants or claim signature failure isolates a
|
||||
+particular claim. A fresh attempt token is not a preserved pre-outage token.
|
||||
+
|
||||
+T04 remains wait/needs_human, depends on T03 and NK-WP-0049-T33, and retains
|
||||
+actual native acceptance. T18 owns actual selected-consumer recovery; T19 owns
|
||||
+retained-factor MFA. Return separate closed issuer/consumer-contract/backend
|
||||
+receipts tied to one attempt. Export source/public signing/TLS hashes, allowed
|
||||
+identifiers, booleans and cleanup facts only; never secret/token/private manifest
|
||||
+or raw provider output. A human wait is not an automatic worker wakeup.
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"status": "verified_source_only",
|
||||
"task_statuses": {
|
||||
"T01": "done",
|
||||
"T02": "done",
|
||||
"T03": "done source-plan only",
|
||||
"T04": "wait needs_human"
|
||||
},
|
||||
"parent_status": "active",
|
||||
"all_existing_task_ids_uuids_and_t04_dependencies_preserved": true,
|
||||
"frozen_packet_all_hashes_unchanged": true,
|
||||
"unrelated_worktree_hashes_preserved": true,
|
||||
"owner_doc_source_and_observer_hashes_match": true,
|
||||
"owner_doc_links_resolve": true,
|
||||
"code_tests_extended": false,
|
||||
"git_sync_and_native_actions": false
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"status": "verified",
|
||||
"commit": "691dc742362eeec45d5bd32d2b468f31a959748e",
|
||||
"primary": "primary/railiance01",
|
||||
"workplan": "SECRETS-WP-0015",
|
||||
"task_bindings": 4,
|
||||
"task_uuids_preserved": true,
|
||||
"T03": "done_source_plan_only",
|
||||
"T04": "wait_needs_human",
|
||||
"required_dependencies_verified": [
|
||||
"SECRETS-WP-0015-T03",
|
||||
"NK-WP-0049-T33"
|
||||
],
|
||||
"unrelated_work_preserved": true,
|
||||
"native_target_gates_closed": 0
|
||||
}
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
---
|
||||
id: SECRETS-WP-0015
|
||||
type: workplan
|
||||
title: "Prepare original KeyCape service selector and isolated consumer continuity"
|
||||
domain: infotech
|
||||
repo: secrets-engine
|
||||
status: active
|
||||
owner: codex
|
||||
topic_slug: custodian
|
||||
created: "2026-10-17"
|
||||
updated: "2026-10-17"
|
||||
flavor: implementation
|
||||
depends_on: []
|
||||
related: [CUST-WP-0080, NK-WP-0049, SECRETS-WP-0012, SECRETS-WP-0008, SECRETS-WP-0013]
|
||||
state_hub_workstream_id: "68a0642e-4908-5260-89c9-3adce60e6a4d"
|
||||
---
|
||||
|
||||
Needed source-owner work for NK-WP-0049-T36/T18. Reviewed against current
|
||||
Lifecycle INTENT, explicit consumer constants/custody source and dated historical
|
||||
proof. Active records the delivered source plan and remaining native owner wait;
|
||||
it is not native assent. Finished0012 remains finished; functional adoption/backend
|
||||
entitlement stay0008T06/0013. No new grant,
|
||||
secret fetch, provider login, production redirect or external message occurred.
|
||||
|
||||
## Establish exact current intended source selector
|
||||
|
||||
```task
|
||||
id: SECRETS-WP-0015-T01
|
||||
status: done
|
||||
priority: high
|
||||
assignee: codex
|
||||
state_hub_task_id: "a3e0e243-edac-5ade-a3d5-f58dac41633a"
|
||||
```
|
||||
|
||||
Completed 2026-10-17 as source review. Current consumer constants and config guards
|
||||
agree with secrets-engine-openbao client/audience, service:secrets-engine,
|
||||
tenant:platform, role secrets-engine and only openbao:login. Producer env selector
|
||||
and historical denied openbao:admin case are independently referenced, without
|
||||
accepting the producer's native role. Prior native issuance7Oct and consumer
|
||||
probe10Oct predate reviewed archive16Oct; they neither prove exact archived bytes
|
||||
nor current native assent. Recorded docs/keycape-isolated-recovery-selector.md.
|
||||
Evidence: Custodian recovery-owner-handoffs-r1 and prior17-source review.
|
||||
|
||||
## Deliver bounded offline public source selector preflight
|
||||
|
||||
```task
|
||||
id: SECRETS-WP-0015-T02
|
||||
status: done
|
||||
priority: high
|
||||
assignee: codex
|
||||
state_hub_task_id: "eab3b758-10ce-5464-b5f7-3a152ee1327a"
|
||||
```
|
||||
|
||||
Completed 2026-10-17 as isolated source preparation. Prepared AST-only source-hash
|
||||
and all-eight-selector-field checker with bounded strict JSON, source drift,
|
||||
duplicate, oversize and symlink negatives. It imports no backend/credential client
|
||||
and never exchanges a token. Tests use public/synthetic metadata only. Canonical
|
||||
integration/publication/projection must be recorded separately; successful output
|
||||
is source correspondence, not native acceptance or a new secret source.
|
||||
|
||||
## Prepare outage-compatible original consumer proof without custody bypass
|
||||
|
||||
```task
|
||||
id: SECRETS-WP-0015-T03
|
||||
status: done
|
||||
priority: high
|
||||
assignee: codex
|
||||
state_hub_task_id: "6262a915-7655-50be-b9f7-481f816d7335"
|
||||
```
|
||||
|
||||
Completed 2026-10-17 as source-plan preparation only. The reviewed owner plan
|
||||
is [keycape-isolated-consumer-continuity-plan.md](../docs/keycape-isolated-consumer-continuity-plan.md),
|
||||
bound to the frozen Custodian `consumer-outage-r1` packet. It distinguishes the
|
||||
restored original issuer check, exact Secrets consumer claim compatibility and
|
||||
actual original OpenBao consumer continuity, preserving the no-file/no-fallback
|
||||
client-secret source contract. Offline founder authority, original TLS/private
|
||||
admission, exact source/runtime/receipt interfaces, positive/negative/equality
|
||||
oracles, timeout, abort and cleanup requirements are reviewable. The plan's done
|
||||
criterion is met; no native or private custody dependency is represented as done.
|
||||
|
||||
The packet includes an unexecuted-on-real-input one-shot claim observer candidate;
|
||||
it is not wired into recovery or ordinary service authentication. Five synthetic
|
||||
tests pass, including seven explicitly noncryptographic claim-parser negatives
|
||||
and source/input refusal checks. The existing exact-source selector preflight
|
||||
passes. These source checks establish neither token signature/native provenance
|
||||
nor client-secret acquisition, OpenBao login, backend entitlement or downstream
|
||||
reconnect. No private archive, original token/key, OpenBao endpoint or native
|
||||
approval was accessed. Source integration/publication/projection are separate
|
||||
coordinator follow-through; the immutable packet retains source hashes and limits.
|
||||
|
||||
Remaining actual owner dependencies are explicit in the plan and T04: NK49T33
|
||||
complete original TLS/archive/private admission; an independently recovered
|
||||
original OpenBao and its custody/OIDC/MFA graph for full consumer continuity;
|
||||
exact native action approval and resource-server negative/revocation receipts.
|
||||
Protected backend operation entitlement stays in existing0008T06/0013.
|
||||
|
||||
## Verify the separately admitted actual isolated consumer result
|
||||
|
||||
```task
|
||||
id: SECRETS-WP-0015-T04
|
||||
status: wait
|
||||
priority: high
|
||||
assignee: codex
|
||||
needs_human: true
|
||||
depends_on: [SECRETS-WP-0015-T03, NK-WP-0049-T33]
|
||||
blocking_reason: "Source plan delivered in T03. Await NK-WP-0049-T33 original TLS/archive/private admission, exact native owner authority, and original OpenBao/custody recovery for actual consumer continuity."
|
||||
state_hub_task_id: "aeec6eb0-39e2-5f7c-8f5d-778133edfc73"
|
||||
```
|
||||
|
||||
Only a separately admitted owner action can establish actual archived registration,
|
||||
issuer trust, native negative checks and consumer continuity. Source selector and
|
||||
historical provider proof do not fill this gate. No production consumer redirect,
|
||||
new grant, live OpenBao read, backend write or retained-factor MFA is authorized.
|
||||
Return exact bounded evidence to NK49T36/T18; MFA remains NK49T19. Human gate is
|
||||
never a worker wakeup. Cross-owner dependency is attached to derived case
|
||||
secrets15-nk49-readiness in the packet; do not strand the wait or invent a driver.
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
---
|
||||
id: SECRETS-WP-0015
|
||||
type: workplan
|
||||
title: "Prepare original KeyCape service selector and isolated consumer continuity"
|
||||
domain: infotech
|
||||
repo: secrets-engine
|
||||
status: ready
|
||||
owner: codex
|
||||
topic_slug: custodian
|
||||
created: "2026-10-17"
|
||||
updated: "2026-10-17"
|
||||
flavor: implementation
|
||||
depends_on: []
|
||||
related: [CUST-WP-0080, NK-WP-0049, SECRETS-WP-0012, SECRETS-WP-0008, SECRETS-WP-0013]
|
||||
state_hub_workstream_id: "68a0642e-4908-5260-89c9-3adce60e6a4d"
|
||||
---
|
||||
|
||||
Needed source-owner work for NK-WP-0049-T36/T18. Reviewed against current
|
||||
Lifecycle INTENT, explicit consumer constants/custody source and dated historical
|
||||
proof. Ready means work can proceed, not native assent. Finished0012 remains
|
||||
finished; functional adoption/backend entitlement stay0008T06/0013. No new grant,
|
||||
secret fetch, provider login, production redirect or external message occurred.
|
||||
|
||||
## Establish exact current intended source selector
|
||||
|
||||
```task
|
||||
id: SECRETS-WP-0015-T01
|
||||
status: done
|
||||
priority: high
|
||||
assignee: codex
|
||||
state_hub_task_id: "a3e0e243-edac-5ade-a3d5-f58dac41633a"
|
||||
```
|
||||
|
||||
Completed 2026-10-17 as source review. Current consumer constants and config guards
|
||||
agree with secrets-engine-openbao client/audience, service:secrets-engine,
|
||||
tenant:platform, role secrets-engine and only openbao:login. Producer env selector
|
||||
and historical denied openbao:admin case are independently referenced, without
|
||||
accepting the producer's native role. Prior native issuance7Oct and consumer
|
||||
probe10Oct predate reviewed archive16Oct; they neither prove exact archived bytes
|
||||
nor current native assent. Recorded docs/keycape-isolated-recovery-selector.md.
|
||||
Evidence: Custodian recovery-owner-handoffs-r1 and prior17-source review.
|
||||
|
||||
## Deliver bounded offline public source selector preflight
|
||||
|
||||
```task
|
||||
id: SECRETS-WP-0015-T02
|
||||
status: done
|
||||
priority: high
|
||||
assignee: codex
|
||||
state_hub_task_id: "eab3b758-10ce-5464-b5f7-3a152ee1327a"
|
||||
```
|
||||
|
||||
Completed 2026-10-17 as isolated source preparation. Prepared AST-only source-hash
|
||||
and all-eight-selector-field checker with bounded strict JSON, source drift,
|
||||
duplicate, oversize and symlink negatives. It imports no backend/credential client
|
||||
and never exchanges a token. Tests use public/synthetic metadata only. Canonical
|
||||
integration/publication/projection must be recorded separately; successful output
|
||||
is source correspondence, not native acceptance or a new secret source.
|
||||
|
||||
## Prepare outage-compatible original consumer proof without custody bypass
|
||||
|
||||
```task
|
||||
id: SECRETS-WP-0015-T03
|
||||
status: todo
|
||||
priority: high
|
||||
assignee: codex
|
||||
state_hub_task_id: "6262a915-7655-50be-b9f7-481f816d7335"
|
||||
```
|
||||
|
||||
Next: map the exact original archive-delivered registration and producer-native
|
||||
checker result to the intended consumer, then prepare a source-reviewed isolated
|
||||
proof/custody plan. Current consumer source requires attended OpenBao memory read
|
||||
and refuses files; ordinary OpenBao/KeyCape outage is therefore a real dependency.
|
||||
Do not add a fallback, persistent consumer copy or unreviewed injection source.
|
||||
Clarify which continuity claim can be proved offline and which requires an exact
|
||||
accepted owner custody/provider path. Bind current original selectors, image/
|
||||
source/TLS metadata, negative cases, timeout/abort and cleanup; retain protected
|
||||
backend operation entitlement in existing0008/0013. Done when that exact plan and
|
||||
remaining owner dependencies are reviewable, without retrieving any value.
|
||||
|
||||
## Verify the separately admitted actual isolated consumer result
|
||||
|
||||
```task
|
||||
id: SECRETS-WP-0015-T04
|
||||
status: wait
|
||||
priority: high
|
||||
assignee: codex
|
||||
needs_human: true
|
||||
depends_on: [SECRETS-WP-0015-T03, NK-WP-0049-T33]
|
||||
blocking_reason: "Await exact consumer proof/custody plan plus original TLS/private admission readiness; actual attended owner path/authority remains required."
|
||||
state_hub_task_id: "aeec6eb0-39e2-5f7c-8f5d-778133edfc73"
|
||||
```
|
||||
|
||||
Only a separately admitted owner action can establish actual archived registration,
|
||||
issuer trust, native negative checks and consumer continuity. Source selector and
|
||||
historical provider proof do not fill this gate. No production consumer redirect,
|
||||
new grant, live OpenBao read, backend write or retained-factor MFA is authorized.
|
||||
Return exact bounded evidence to NK49T36/T18; MFA remains NK49T19. Human gate is
|
||||
never a worker wakeup. Cross-owner dependency is attached to derived case
|
||||
secrets15-nk49-readiness in the packet; do not strand the wait or invent a driver.
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"http_status": 201,
|
||||
"id": "febffe7e-9fdd-4969-a3b8-55edcb90d214",
|
||||
"event_type": "note",
|
||||
"workplan_id": "dfadb19b-445e-59c6-bcd6-48e87b912c52",
|
||||
"summary": "Source checkpoints published and verified: NetKingdom c52ca7f405416d437951844c0640b86e677c3523 adds exact-one original client guard and source-review tasks NK-WP-0048-T22/T23 and NK-WP-0049-T38; 61 task bindings, all58 prior task metadata and unrelated staged/working files preserved. Secrets Engine 691dc742362eeec45d5bd32d2b468f31a959748e delivers SECRETS-WP-0015-T03 source custody/consumer plan; all4 task UUIDs and T04 human-wait dependencies verified. Runtime/storage/registration/scanner-response review candidates are prepared locally; no new native authority, paid run, credential access, residual promotion or security gate closure. All16 target native gates remain open. User-directed NetKingdom source/history lookup found recorded StorageShare disaster guide publication in commit31f483966cdfca4df1d326dee3ec0b6d33ea0e5e at2026-10-16T18:01:01Z: Backup account/railiance-backups/net-kingdom-identity/net-kingdom-recovery-57d1940947aa25ff-START-HERE.md plus ZIP/checksum, all3 recorded readback-verified. Current local guide hash matches actual publication receipt; current remote visibility and original TLS certificate/key backup remain unverified. New exact source-history followthrough receipt retained in storage-share-tls-r1/source-history-followthrough-r2.json. Remaining coordinator evidence publication is live CUST-WP-0080 follow-through; broad goal remains active."
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
{
|
||||
"exit_code": 0,
|
||||
"commit": "c52ca7f405416d437951844c0640b86e677c3523",
|
||||
"base": "70f408ca2389bf3722a91a03832fc6e8587355e5",
|
||||
"files": [
|
||||
{
|
||||
"path": "tools/bootstrap-recovery/isolated-keycape.py",
|
||||
"sha256": "86f37add7221e4c73e3f9d878c09a3cc81061627cbf024ed6887d973d929b718"
|
||||
},
|
||||
{
|
||||
"path": "tests/test_isolated_keycape_recovery.py",
|
||||
"sha256": "5f729e077db51dd6b17d00dc3eb71c0e652849f55fe68505a07befa663c91dea"
|
||||
},
|
||||
{
|
||||
"path": "tests/isolated-keycape-native-fixture-manifest.json",
|
||||
"sha256": "936ee435be04b27f391391e7dda02def69e153bde3adcce92d569f33f308db2e"
|
||||
},
|
||||
{
|
||||
"path": "workplans/NK-WP-0048-security-case-types.md",
|
||||
"sha256": "37daaec6502e4f9a91bb6c93b8fb475d26d6f3de015d172a89508bab798f635f"
|
||||
},
|
||||
{
|
||||
"path": "workplans/NK-WP-0049-bootstrap-secret-free-recovery-handoff.md",
|
||||
"sha256": "cba3233883e9a5b429aaea1b8eacd250c6efcf5e484c4284ddc97e8e52697085"
|
||||
}
|
||||
],
|
||||
"identifier_assignments": {
|
||||
"schema": "repo-manager.identifier-assignment.v1",
|
||||
"ok": true,
|
||||
"executed": true,
|
||||
"repo": "net-kingdom",
|
||||
"namespace": "helixforge",
|
||||
"assignments": [
|
||||
{
|
||||
"kind": "task",
|
||||
"record_id": "NK-WP-0048-T22",
|
||||
"uuid": "ea50d93b-0d04-55d2-98c4-9b6c3fe925b1",
|
||||
"path": "workplans/NK-WP-0048-security-case-types.md"
|
||||
},
|
||||
{
|
||||
"kind": "task",
|
||||
"record_id": "NK-WP-0048-T23",
|
||||
"uuid": "6e7cd483-c7af-53a2-9d0a-3d76b6fb49ee",
|
||||
"path": "workplans/NK-WP-0048-security-case-types.md"
|
||||
},
|
||||
{
|
||||
"kind": "task",
|
||||
"record_id": "NK-WP-0049-T38",
|
||||
"uuid": "76dde6b9-5ee8-50d3-bf15-461d6d5f29b8",
|
||||
"path": "workplans/NK-WP-0049-bootstrap-secret-free-recovery-handoff.md"
|
||||
}
|
||||
],
|
||||
"historical_invalid_identifiers": [],
|
||||
"historical_identity_collisions": [],
|
||||
"files_changed": [
|
||||
"workplans/NK-WP-0048-security-case-types.md",
|
||||
"workplans/NK-WP-0049-bootstrap-secret-free-recovery-handoff.md"
|
||||
]
|
||||
},
|
||||
"native_target_gates_closed": 0
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"blocked_blob_ids": [], "scanned_blobs": 5, "scanner_sha256": "88f91962aa2f93ac6ab281d553b9e125f5197bbbce38f9f2437f7299c32e5509", "scanner_version": "8.30.1", "scope": "changed-staged-blobs", "status": "clean"}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
[main c52ca7f] fix(recovery): require one original client and refine native owner gates
|
||||
5 files changed, 270 insertions(+), 26 deletions(-)
|
||||
|
|
@ -0,0 +1,410 @@
|
|||
{
|
||||
"repo_slug": "net-kingdom",
|
||||
"repo_path": "/home/worsch/net-kingdom",
|
||||
"source_revision": "c52ca7f405416d437951844c0640b86e677c3523",
|
||||
"source_revision_reason": null,
|
||||
"issues": [
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-24",
|
||||
"message": "Repo classification advisory: capability_tag 'security' is not a recommended family tag (allowed, check for synonym)",
|
||||
"file_path": "",
|
||||
"db_id": "",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-35",
|
||||
"message": "Repo Manager warning: workplans/: repository uses more than one workplan prefix: ['NET-WP', 'NK-WP']",
|
||||
"file_path": "workplans/",
|
||||
"db_id": "",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-33",
|
||||
"message": "WORK-RECORDS.md is missing or stale \u2014 regenerate via fix-consistency (CUST-WP-0061-T04 generated work-record index)",
|
||||
"file_path": "WORK-RECORDS.md",
|
||||
"db_id": "",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": true
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-37",
|
||||
"message": "Residual workplan 'nk-wp-0011' has no origin/origin_ref provenance (not invented)",
|
||||
"file_path": "workplans/NK-WP-0011-enterprise-federation-saml.md",
|
||||
"db_id": "1075448f-d533-5f9e-94b7-c3adfe151a07",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-20",
|
||||
"message": "Workplan dependency target 'USER-WP-0020' is not linked to State Hub",
|
||||
"file_path": "workplans/NK-WP-0022-railiance01-identity-cutover-and-coulombcore-retirement.md",
|
||||
"db_id": "",
|
||||
"file_value": "USER-WP-0020",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-20",
|
||||
"message": "Workplan dependency target 'KEY-WP-0004' is not linked to State Hub",
|
||||
"file_path": "workplans/NK-WP-0022-railiance01-identity-cutover-and-coulombcore-retirement.md",
|
||||
"db_id": "",
|
||||
"file_value": "KEY-WP-0004",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-20",
|
||||
"message": "Workplan dependency target 'USER-WP-0020' is not linked to State Hub",
|
||||
"file_path": "workplans/NK-WP-0023-user-engine-portal-platform-integration.md",
|
||||
"db_id": "",
|
||||
"file_value": "USER-WP-0020",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-20",
|
||||
"message": "Workplan dependency target 'KEY-WP-0004' is not linked to State Hub",
|
||||
"file_path": "workplans/NK-WP-0023-user-engine-portal-platform-integration.md",
|
||||
"db_id": "",
|
||||
"file_value": "KEY-WP-0004",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-20",
|
||||
"message": "Workplan dependency target 'USER-WP-0021' is not linked to State Hub",
|
||||
"file_path": "workplans/NK-WP-0024-user-engine-portal-integration-expansion.md",
|
||||
"db_id": "",
|
||||
"file_value": "USER-WP-0021",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-20",
|
||||
"message": "Workplan dependency target 'FLEX-WP-0009' is not linked to State Hub",
|
||||
"file_path": "workplans/NK-WP-0024-user-engine-portal-integration-expansion.md",
|
||||
"db_id": "",
|
||||
"file_value": "FLEX-WP-0009",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-20",
|
||||
"message": "Workplan dependency target 'AUDIT-WP-0003' is not linked to State Hub",
|
||||
"file_path": "workplans/NK-WP-0024-user-engine-portal-integration-expansion.md",
|
||||
"db_id": "",
|
||||
"file_value": "AUDIT-WP-0003",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-20",
|
||||
"message": "Workplan dependency target 'EMAIL-WP-0004' is not linked to State Hub",
|
||||
"file_path": "workplans/NK-WP-0024-user-engine-portal-integration-expansion.md",
|
||||
"db_id": "",
|
||||
"file_value": "EMAIL-WP-0004",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-20",
|
||||
"message": "Workplan dependency target 'USER-WP-0022' is not linked to State Hub",
|
||||
"file_path": "workplans/NK-WP-0025-public-self-registration-and-application-jit.md",
|
||||
"db_id": "",
|
||||
"file_value": "USER-WP-0022",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-20",
|
||||
"message": "Workplan dependency target 'KEY-WP-0008' is not linked to State Hub",
|
||||
"file_path": "workplans/NK-WP-0025-public-self-registration-and-application-jit.md",
|
||||
"db_id": "",
|
||||
"file_value": "KEY-WP-0008",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-20",
|
||||
"message": "Workplan dependency target 'CSOC-WP-0003' is not linked to State Hub",
|
||||
"file_path": "workplans/NK-WP-0025-public-self-registration-and-application-jit.md",
|
||||
"db_id": "",
|
||||
"file_value": "CSOC-WP-0003",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-37",
|
||||
"message": "Residual workplan 'nk-wp-0027' has no origin/origin_ref provenance (not invented)",
|
||||
"file_path": "workplans/NK-WP-0027-reef-placement-reconciliation.md",
|
||||
"db_id": "965ad365-6b81-50a1-a2a3-2d0c1fcce0b4",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-37",
|
||||
"message": "Residual workplan 'nk-wp-0031' has no origin/origin_ref provenance (not invented)",
|
||||
"file_path": "workplans/NK-WP-0031-deterministic-posture-feedback.md",
|
||||
"db_id": "9d7b04f9-3803-5613-b7a5-8bd606c77f5a",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-37",
|
||||
"message": "Residual workplan 'nk-wp-0040' has no origin/origin_ref provenance (not invented)",
|
||||
"file_path": "workplans/NK-WP-0040-execution-attribution-receipt.md",
|
||||
"db_id": "e2533f3a-aa43-59b3-bff3-8e64b6149487",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-22",
|
||||
"message": "Task description drift 'NK-WP-0048-T14': file content differs from DB (file wins)",
|
||||
"file_path": "workplans/NK-WP-0048-security-case-types.md#NK-WP-0048-T14",
|
||||
"db_id": "fce95440-a25b-5f27-8ef3-a3d182099113",
|
||||
"file_value": "Owner: NetKingdom. Next action: bind the completed T21 PostgreSQL journal to\nan admitted dedicated CNPG consumer through",
|
||||
"db_value": "Owner: NetKingdom. Next action: bind the completed T21 PostgreSQL journal to\nan admitted dedicated CNPG consumer through",
|
||||
"fixable": true
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-22",
|
||||
"message": "Task description drift 'NK-WP-0048-T15': file content differs from DB (file wins)",
|
||||
"file_path": "workplans/NK-WP-0048-security-case-types.md#NK-WP-0048-T15",
|
||||
"db_id": "1b825705-4848-5edc-832f-b1622cd9bdb7",
|
||||
"file_value": "Owner: NetKingdom for registration state, with Warden owning kernel evidence\nadmission. T22 records the completed source",
|
||||
"db_value": "Owner: NetKingdom for registration state, with Warden owning kernel evidence\nadmission. Next action: select the exact ex",
|
||||
"fixable": true
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-22",
|
||||
"message": "Task description drift 'NK-WP-0048-T16': file content differs from DB (file wins)",
|
||||
"file_path": "workplans/NK-WP-0048-security-case-types.md#NK-WP-0048-T16",
|
||||
"db_id": "200bf500-5084-5ae7-be26-3033fe1f296e",
|
||||
"file_value": "Owner: NetKingdom for descriptor/type source and exact checker artifact; Warden\nindependently owns global provenance/adm",
|
||||
"db_value": "Owner: NetKingdom for descriptor/type source and exact checker artifact; Warden\nindependently owns global provenance/adm",
|
||||
"fixable": true
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-11",
|
||||
"message": "Derived task 'NK-WP-0048-T22' is absent from this projection",
|
||||
"file_path": "workplans/NK-WP-0048-security-case-types.md#NK-WP-0048-T22",
|
||||
"db_id": "ea50d93b-0d04-55d2-98c4-9b6c3fe925b1",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": true
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-11",
|
||||
"message": "Derived task 'NK-WP-0048-T23' is absent from this projection",
|
||||
"file_path": "workplans/NK-WP-0048-security-case-types.md#NK-WP-0048-T23",
|
||||
"db_id": "6e7cd483-c7af-53a2-9d0a-3d76b6fb49ee",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": true
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-22",
|
||||
"message": "Task description drift 'NK-WP-0049-T36': file content differs from DB (file wins)",
|
||||
"file_path": "workplans/NK-WP-0049-bootstrap-secret-free-recovery-handoff.md#NK-WP-0049-T36",
|
||||
"db_id": "8b72334b-fc27-5707-a189-bad345eaf3bc",
|
||||
"file_value": "**Accountable worker:** NetKingdom codex with KeyCape and the selected existing\nservice consumer's owner. **Next action:",
|
||||
"db_value": "**Accountable worker:** NetKingdom codex with KeyCape and the selected existing\nservice consumer's owner. **Next action:",
|
||||
"fixable": true
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-11",
|
||||
"message": "Derived task 'NK-WP-0049-T38' is absent from this projection",
|
||||
"file_path": "workplans/NK-WP-0049-bootstrap-secret-free-recovery-handoff.md#NK-WP-0049-T38",
|
||||
"db_id": "76dde6b9-5ee8-50d3-bf15-461d6d5f29b8",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": true
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-22",
|
||||
"message": "Task description drift 'NK-WP-0049-T03': file content differs from DB (file wins)",
|
||||
"file_path": "workplans/NK-WP-0049-bootstrap-secret-free-recovery-handoff.md#NK-WP-0049-T03",
|
||||
"db_id": "d68cd4d3-1ba3-530e-88f9-26ebb8dd6eac",
|
||||
"file_value": "**Accountable worker:** codex. Service/credential-owner acceptance remains with\nthe named owner boundary.\n\nOwner boundar",
|
||||
"db_value": "**Accountable worker:** codex. Service/credential-owner acceptance remains with\nthe named owner boundary.\n\nOwner boundar",
|
||||
"fixable": true
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-20",
|
||||
"message": "Workplan dependency target 'RAIL-PL-WP-0002' is not linked to State Hub",
|
||||
"file_path": "workplans/archived/260702-NET-WP-0017-it-security-readiness-for-user-onboarding.md",
|
||||
"db_id": "",
|
||||
"file_value": "RAIL-PL-WP-0002",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "INFO",
|
||||
"check_id": "C-08",
|
||||
"message": "Retired DB workstream 'nk-wp-0035@retired-20260908' (id=064c5e8b\u2026, status=archived) has no backing workplan file \u2014 projection tombstone, not live work",
|
||||
"file_path": "",
|
||||
"db_id": "064c5e8b-7852-4d7f-a5fa-e26e406ab8e0",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "INFO",
|
||||
"check_id": "C-08",
|
||||
"message": "Retired DB workstream 'net-kingdom-adhoc-2026-07-02@retired-20260827' (id=67c1c7ac\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work",
|
||||
"file_path": "",
|
||||
"db_id": "67c1c7ac-d8b1-41dc-a81a-4e43f1afd068",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "INFO",
|
||||
"check_id": "C-08",
|
||||
"message": "Retired DB workstream 'net-kingdom-adhoc-2026-06-14@retired-20260827' (id=c6f3d6bf\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work",
|
||||
"file_path": "",
|
||||
"db_id": "c6f3d6bf-4916-490d-96ce-092d2776d7e7",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "INFO",
|
||||
"check_id": "C-08",
|
||||
"message": "Retired DB workstream 'adhoc-2026-08-14@retired-20260827' (id=a5097121\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work",
|
||||
"file_path": "",
|
||||
"db_id": "a5097121-1461-59f8-81fa-e6ecef527337",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "INFO",
|
||||
"check_id": "C-08",
|
||||
"message": "Retired DB workstream 'adhoc-2026-08-23@retired-20260827' (id=e25ba5fa\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work",
|
||||
"file_path": "",
|
||||
"db_id": "e25ba5fa-eaae-5039-8d93-a69c6d837fc4",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-26",
|
||||
"message": "Workplan id 'NET-WP-0020' uses prefix 'NET-WP' but repo canonical prefix is 'NK-WP' \u2014 new plans must conform",
|
||||
"file_path": "workplans/NET-WP-0020-openbao-unseal-custody-and-ssh-automation.md",
|
||||
"db_id": "",
|
||||
"file_value": "NET-WP-0020",
|
||||
"db_value": "NK-WP",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-26",
|
||||
"message": "Workplan id 'NET-WP-0015' uses prefix 'NET-WP' but repo canonical prefix is 'NK-WP' \u2014 new plans must conform",
|
||||
"file_path": "workplans/archived/260603-NET-WP-0015-platform-root-custody-and-openbao-identity-bootstrap.md",
|
||||
"db_id": "",
|
||||
"file_value": "NET-WP-0015",
|
||||
"db_value": "NK-WP",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-26",
|
||||
"message": "Workplan id 'NET-WP-0016' uses prefix 'NET-WP' but repo canonical prefix is 'NK-WP' \u2014 new plans must conform",
|
||||
"file_path": "workplans/archived/260603-NET-WP-0016-guided-security-bootstrap-experience.md",
|
||||
"db_id": "",
|
||||
"file_value": "NET-WP-0016",
|
||||
"db_value": "NK-WP",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-26",
|
||||
"message": "Workplan id 'NET-WP-0018' uses prefix 'NET-WP' but repo canonical prefix is 'NK-WP' \u2014 new plans must conform",
|
||||
"file_path": "workplans/archived/260604-NET-WP-0018-bootstrap-automation-and-rebuild-readiness.md",
|
||||
"db_id": "",
|
||||
"file_value": "NET-WP-0018",
|
||||
"db_value": "NK-WP",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-26",
|
||||
"message": "Workplan id 'NET-WP-0017' uses prefix 'NET-WP' but repo canonical prefix is 'NK-WP' \u2014 new plans must conform",
|
||||
"file_path": "workplans/archived/260702-NET-WP-0017-it-security-readiness-for-user-onboarding.md",
|
||||
"db_id": "",
|
||||
"file_value": "NET-WP-0017",
|
||||
"db_value": "NK-WP",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-26",
|
||||
"message": "Workplan id 'NET-WP-0019' uses prefix 'NET-WP' but repo canonical prefix is 'NK-WP' \u2014 new plans must conform",
|
||||
"file_path": "workplans/archived/260702-NET-WP-0019-t06-adjacent-user-lifecycle-dry-run-polish.md",
|
||||
"db_id": "",
|
||||
"file_value": "NET-WP-0019",
|
||||
"db_value": "NK-WP",
|
||||
"fixable": false
|
||||
}
|
||||
],
|
||||
"fixes_applied": [
|
||||
"bindings: synced 64/64",
|
||||
"C-17 cleared: pushed 1 backlogged commit(s)",
|
||||
"C-33 fixed: regenerated WORK-RECORDS.md",
|
||||
"C-22 fixed: task fce95440\u2026 description updated",
|
||||
"C-22 fixed: task 1b825705\u2026 description updated",
|
||||
"C-22 fixed: task 200bf500\u2026 description updated",
|
||||
"C-11 fixed: task 'NK-WP-0048-T22' \u2192 ea50d93b\u2026",
|
||||
"C-11 fixed: task 'NK-WP-0048-T23' \u2192 6e7cd483\u2026",
|
||||
"C-22 fixed: task 8b72334b\u2026 description updated",
|
||||
"C-11 fixed: task 'NK-WP-0049-T38' \u2192 76dde6b9\u2026",
|
||||
"C-22 fixed: task d68cd4d3\u2026 description updated",
|
||||
"brief: .custodian-brief.md updated",
|
||||
"push: pushed"
|
||||
],
|
||||
"summary": {
|
||||
"fail": 0,
|
||||
"automation_error": 0,
|
||||
"warn": 33,
|
||||
"info": 5
|
||||
},
|
||||
"result": "warn"
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
WARN: git commit failed for writeback: Generated-only commits rejected: staged
|
||||
|
|
@ -0,0 +1,911 @@
|
|||
{
|
||||
"ok": true,
|
||||
"status": "applied",
|
||||
"repo_slug": "net-kingdom",
|
||||
"commit": "c52ca7f405416d437951844c0640b86e677c3523",
|
||||
"requests": 2,
|
||||
"elapsed_ms": 6900.3,
|
||||
"git": {
|
||||
"upstream": "origin/main",
|
||||
"behind": 0,
|
||||
"ahead": 0
|
||||
},
|
||||
"identifiers": {
|
||||
"schema": "repo-manager.identifier-assignment.v1",
|
||||
"ok": true,
|
||||
"executed": true,
|
||||
"repo": "net-kingdom",
|
||||
"namespace": "helixforge",
|
||||
"assignments": [],
|
||||
"historical_invalid_identifiers": [],
|
||||
"historical_identity_collisions": [],
|
||||
"files_changed": []
|
||||
},
|
||||
"receipt": {
|
||||
"schema": "state-hub.repository-projection-reconcile.v1",
|
||||
"instance_role": "primary",
|
||||
"instance_label": "railiance01",
|
||||
"expected_commit": "c52ca7f405416d437951844c0640b86e677c3523",
|
||||
"derived_commit": "c52ca7f405416d437951844c0640b86e677c3523",
|
||||
"outcome": {
|
||||
"schema": "state-hub.projection-reset.v1",
|
||||
"repo_slug": "net-kingdom",
|
||||
"commit": "c52ca7f405416d437951844c0640b86e677c3523",
|
||||
"status": "applied",
|
||||
"counts": {
|
||||
"created": 0,
|
||||
"updated": 64,
|
||||
"retired": 0,
|
||||
"refused": 0,
|
||||
"released": 0,
|
||||
"created_tasks": 0,
|
||||
"updated_tasks": 3,
|
||||
"cancelled_tasks": 0,
|
||||
"created_edges": 0,
|
||||
"removed_edges": 0,
|
||||
"unresolved_edges": 1,
|
||||
"external_edges": 77
|
||||
},
|
||||
"created": [],
|
||||
"updated": [
|
||||
"NET-WP-0015",
|
||||
"NET-WP-0016",
|
||||
"NET-WP-0017",
|
||||
"NET-WP-0018",
|
||||
"NET-WP-0019",
|
||||
"NET-WP-0020",
|
||||
"NK-WP-0001",
|
||||
"NK-WP-0002",
|
||||
"NK-WP-0003",
|
||||
"NK-WP-0004",
|
||||
"NK-WP-0005",
|
||||
"NK-WP-0006",
|
||||
"NK-WP-0007",
|
||||
"NK-WP-0008",
|
||||
"NK-WP-0009",
|
||||
"NK-WP-0010",
|
||||
"NK-WP-0011",
|
||||
"NK-WP-0012",
|
||||
"NK-WP-0013",
|
||||
"NK-WP-0014",
|
||||
"NK-WP-0015",
|
||||
"NK-WP-0016",
|
||||
"NK-WP-0017",
|
||||
"NK-WP-0018",
|
||||
"NK-WP-0019",
|
||||
"NK-WP-0021",
|
||||
"NK-WP-0022",
|
||||
"NK-WP-0023",
|
||||
"NK-WP-0024",
|
||||
"NK-WP-0025",
|
||||
"NK-WP-0026",
|
||||
"NK-WP-0027",
|
||||
"NK-WP-0028",
|
||||
"NK-WP-0029",
|
||||
"NK-WP-0030",
|
||||
"NK-WP-0031",
|
||||
"NK-WP-0032",
|
||||
"NK-WP-0033",
|
||||
"NK-WP-0034",
|
||||
"NK-WP-0035",
|
||||
"NK-WP-0036",
|
||||
"NK-WP-0037",
|
||||
"NK-WP-0038",
|
||||
"NK-WP-0039",
|
||||
"NK-WP-0040",
|
||||
"NK-WP-0041",
|
||||
"NK-WP-0042",
|
||||
"NK-WP-0043",
|
||||
"NK-WP-0044",
|
||||
"NK-WP-0045",
|
||||
"NK-WP-0046",
|
||||
"NK-WP-0047",
|
||||
"NK-WP-0048",
|
||||
"NK-WP-0049",
|
||||
"NK-WP-0050",
|
||||
"NK-WP-0051",
|
||||
"NK-WP-ADHOC-2026-06-14",
|
||||
"NK-WP-ADHOC-2026-07-02",
|
||||
"NK-WP-ADHOC-2026-08-14",
|
||||
"NK-WP-ADHOC-2026-08-23",
|
||||
"NK-WP-ADHOC-2026-10-03",
|
||||
"NK-WP-ADHOC-2026-10-10",
|
||||
"NK-WP-ADHOC-2026-10-11",
|
||||
"NK-WP-ADHOC-2026-10-16"
|
||||
],
|
||||
"retired": [],
|
||||
"released": [],
|
||||
"created_tasks": [],
|
||||
"updated_tasks": [
|
||||
"NK-WP-0048-T22",
|
||||
"NK-WP-0048-T23",
|
||||
"NK-WP-0049-T38"
|
||||
],
|
||||
"cancelled_tasks": [],
|
||||
"created_edges": [],
|
||||
"removed_edges": [],
|
||||
"unresolved_edges": [
|
||||
{
|
||||
"workplan": "NK-WP-0006",
|
||||
"from": "NK-WP-0006",
|
||||
"target": "NK-WP-0001",
|
||||
"reason": "missing"
|
||||
}
|
||||
],
|
||||
"external_edges": [
|
||||
{
|
||||
"workplan": "NK-WP-0008",
|
||||
"from": "NK-WP-0008",
|
||||
"target": "NK-WP-0006",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "053c6d96-9396-40c9-a2e5-c36531e7810d",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "2eb8a5e0-4e33-4ed3-8996-a2eec3aad862",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0050",
|
||||
"from": "NK-WP-0050-T03",
|
||||
"target": "RPF-WP-0056-T03",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "06ba98d5-609e-5aaa-9bf7-4c4f4460e377",
|
||||
"from_task_id": "5a3aaf57-de5c-5a03-bc99-9bcf2fc5d95e",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "a82762eb-bb6d-5600-89ca-a81ada2eba9f"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0050",
|
||||
"from": "NK-WP-0050-T03",
|
||||
"target": "NK-WP-0050-T02",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "06ba98d5-609e-5aaa-9bf7-4c4f4460e377",
|
||||
"from_task_id": "5a3aaf57-de5c-5a03-bc99-9bcf2fc5d95e",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "a9dadd07-f136-5dc7-9229-7a9dbb941f0d"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0050",
|
||||
"from": "NK-WP-0050-T02",
|
||||
"target": "NK-WP-0050-T01",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "06ba98d5-609e-5aaa-9bf7-4c4f4460e377",
|
||||
"from_task_id": "a9dadd07-f136-5dc7-9229-7a9dbb941f0d",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "64893d94-9717-5812-b8e3-7cabe095fcdc"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0017",
|
||||
"from": "NK-WP-0017",
|
||||
"target": "NK-WP-0015",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "08398d26-cadf-44bc-97ee-67da790040e6",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "343e035d-41e1-4fc4-b209-6872e4a5fdc8",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0011",
|
||||
"from": "NK-WP-0011",
|
||||
"target": "NK-WP-0006",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "1075448f-d533-5f9e-94b7-c3adfe151a07",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "2eb8a5e0-4e33-4ed3-8996-a2eec3aad862",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0011",
|
||||
"from": "NK-WP-0011",
|
||||
"target": "NK-WP-0004",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "1075448f-d533-5f9e-94b7-c3adfe151a07",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "d9cf7c4b-886b-4cd1-ad7b-99c4e1929c9e",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0011",
|
||||
"from": "NK-WP-0011",
|
||||
"target": "NK-WP-0003",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "1075448f-d533-5f9e-94b7-c3adfe151a07",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "f24cefd4-a09b-4fa1-9b25-94bf783b425e",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0011",
|
||||
"from": "NK-WP-0011-T03",
|
||||
"target": "NK-WP-0011-T02",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "1075448f-d533-5f9e-94b7-c3adfe151a07",
|
||||
"from_task_id": "32d1411b-10a4-5a8b-8f43-99ac46d83908",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "2fe6f100-3a5d-563e-b033-7d7b846ae487"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0011",
|
||||
"from": "NK-WP-0011-T07",
|
||||
"target": "NK-WP-0011-T03",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "1075448f-d533-5f9e-94b7-c3adfe151a07",
|
||||
"from_task_id": "38998c68-29bf-50d2-8c8d-0c75184d5833",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "32d1411b-10a4-5a8b-8f43-99ac46d83908"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0011",
|
||||
"from": "NK-WP-0011-T07",
|
||||
"target": "NK-WP-0011-T04",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "1075448f-d533-5f9e-94b7-c3adfe151a07",
|
||||
"from_task_id": "38998c68-29bf-50d2-8c8d-0c75184d5833",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "6697a994-7343-5ea8-8b37-bc3b921e5a9b"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0011",
|
||||
"from": "NK-WP-0011-T07",
|
||||
"target": "NK-WP-0011-T05",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "1075448f-d533-5f9e-94b7-c3adfe151a07",
|
||||
"from_task_id": "38998c68-29bf-50d2-8c8d-0c75184d5833",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "d845380d-3dbc-5e59-8f2b-5a4d1b32d89d"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0011",
|
||||
"from": "NK-WP-0011-T04",
|
||||
"target": "NK-WP-0011-T03",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "1075448f-d533-5f9e-94b7-c3adfe151a07",
|
||||
"from_task_id": "6697a994-7343-5ea8-8b37-bc3b921e5a9b",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "32d1411b-10a4-5a8b-8f43-99ac46d83908"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0011",
|
||||
"from": "NK-WP-0011-T06",
|
||||
"target": "NK-WP-0011-T03",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "1075448f-d533-5f9e-94b7-c3adfe151a07",
|
||||
"from_task_id": "9cb7fd93-c16e-5102-83ce-195b3aa87446",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "32d1411b-10a4-5a8b-8f43-99ac46d83908"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0011",
|
||||
"from": "NK-WP-0011-T06",
|
||||
"target": "NK-WP-0011-T04",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "1075448f-d533-5f9e-94b7-c3adfe151a07",
|
||||
"from_task_id": "9cb7fd93-c16e-5102-83ce-195b3aa87446",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "6697a994-7343-5ea8-8b37-bc3b921e5a9b"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0011",
|
||||
"from": "NK-WP-0011-T06",
|
||||
"target": "NK-WP-0011-T05",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "1075448f-d533-5f9e-94b7-c3adfe151a07",
|
||||
"from_task_id": "9cb7fd93-c16e-5102-83ce-195b3aa87446",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "d845380d-3dbc-5e59-8f2b-5a4d1b32d89d"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0011",
|
||||
"from": "NK-WP-0011-T05",
|
||||
"target": "NK-WP-0011-T04",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "1075448f-d533-5f9e-94b7-c3adfe151a07",
|
||||
"from_task_id": "d845380d-3dbc-5e59-8f2b-5a4d1b32d89d",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "6697a994-7343-5ea8-8b37-bc3b921e5a9b"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0011",
|
||||
"from": "NK-WP-0011-T09",
|
||||
"target": "NK-WP-0011-T03",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "1075448f-d533-5f9e-94b7-c3adfe151a07",
|
||||
"from_task_id": "d9dc4292-6b66-5797-9ff9-a1a4a556278e",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "32d1411b-10a4-5a8b-8f43-99ac46d83908"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0011",
|
||||
"from": "NK-WP-0011-T09",
|
||||
"target": "NK-WP-0011-T07",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "1075448f-d533-5f9e-94b7-c3adfe151a07",
|
||||
"from_task_id": "d9dc4292-6b66-5797-9ff9-a1a4a556278e",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "38998c68-29bf-50d2-8c8d-0c75184d5833"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0011",
|
||||
"from": "NK-WP-0011-T09",
|
||||
"target": "NK-WP-0011-T08",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "1075448f-d533-5f9e-94b7-c3adfe151a07",
|
||||
"from_task_id": "d9dc4292-6b66-5797-9ff9-a1a4a556278e",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "e5f44ddc-9645-5f61-b84c-da5ab9cccb6d"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0011",
|
||||
"from": "NK-WP-0011-T08",
|
||||
"target": "NK-WP-0011-T02",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "1075448f-d533-5f9e-94b7-c3adfe151a07",
|
||||
"from_task_id": "e5f44ddc-9645-5f61-b84c-da5ab9cccb6d",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "2fe6f100-3a5d-563e-b033-7d7b846ae487"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0011",
|
||||
"from": "NK-WP-0011-T08",
|
||||
"target": "NK-WP-0011-T03",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "1075448f-d533-5f9e-94b7-c3adfe151a07",
|
||||
"from_task_id": "e5f44ddc-9645-5f61-b84c-da5ab9cccb6d",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "32d1411b-10a4-5a8b-8f43-99ac46d83908"
|
||||
},
|
||||
{
|
||||
"workplan": "NET-WP-0016",
|
||||
"from": "NET-WP-0016",
|
||||
"target": "NET-WP-0015",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "16069174-6698-4855-ad9e-5092c8571f38",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "6b9c25e4-1008-429a-8de6-54361872c0dd",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NET-WP-0016",
|
||||
"from": "NET-WP-0016",
|
||||
"target": "NK-WP-0012",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "16069174-6698-4855-ad9e-5092c8571f38",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "9b8e4afc-eb71-47d9-8750-799a082b320a",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0049",
|
||||
"from": "NK-WP-0049-T18",
|
||||
"target": "NK-WP-0049-T33",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "17d315f0-829e-57c7-85cc-3a7914152804",
|
||||
"from_task_id": "141dd773-c1fa-56c1-a852-bbe2372e5125",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "56c8d469-7a10-5d50-a30e-95cbf3cd4756"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0049",
|
||||
"from": "NK-WP-0049-T18",
|
||||
"target": "NK-WP-0049-T32",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "17d315f0-829e-57c7-85cc-3a7914152804",
|
||||
"from_task_id": "141dd773-c1fa-56c1-a852-bbe2372e5125",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "cd78dbb7-a8f2-5754-8788-6eb1b7d97741"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0049",
|
||||
"from": "NK-WP-0049-T35",
|
||||
"target": "NK-WP-0049-T34",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "17d315f0-829e-57c7-85cc-3a7914152804",
|
||||
"from_task_id": "1bfd1703-589f-5511-bad5-812d860e4a71",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "821b3a56-6f36-5812-abc9-5a00e37cb2e7"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0049",
|
||||
"from": "NK-WP-0049-T33",
|
||||
"target": "NK-WP-0049-T35",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "17d315f0-829e-57c7-85cc-3a7914152804",
|
||||
"from_task_id": "56c8d469-7a10-5d50-a30e-95cbf3cd4756",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "1bfd1703-589f-5511-bad5-812d860e4a71"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0049",
|
||||
"from": "NK-WP-0049-T33",
|
||||
"target": "NK-WP-0049-T34",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "17d315f0-829e-57c7-85cc-3a7914152804",
|
||||
"from_task_id": "56c8d469-7a10-5d50-a30e-95cbf3cd4756",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "821b3a56-6f36-5812-abc9-5a00e37cb2e7"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0049",
|
||||
"from": "NK-WP-0049-T33",
|
||||
"target": "NK-WP-0049-T36",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "17d315f0-829e-57c7-85cc-3a7914152804",
|
||||
"from_task_id": "56c8d469-7a10-5d50-a30e-95cbf3cd4756",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "8b72334b-fc27-5707-a189-bad345eaf3bc"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0049",
|
||||
"from": "NK-WP-0049-T33",
|
||||
"target": "NK-WP-0049-T32",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "17d315f0-829e-57c7-85cc-3a7914152804",
|
||||
"from_task_id": "56c8d469-7a10-5d50-a30e-95cbf3cd4756",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "cd78dbb7-a8f2-5754-8788-6eb1b7d97741"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0049",
|
||||
"from": "NK-WP-0049-T36",
|
||||
"target": "NK-WP-0049-T34",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "17d315f0-829e-57c7-85cc-3a7914152804",
|
||||
"from_task_id": "8b72334b-fc27-5707-a189-bad345eaf3bc",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "821b3a56-6f36-5812-abc9-5a00e37cb2e7"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0049",
|
||||
"from": "NK-WP-0049-T03",
|
||||
"target": "NK-WP-0049-T02",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "17d315f0-829e-57c7-85cc-3a7914152804",
|
||||
"from_task_id": "d68cd4d3-1ba3-530e-88f9-26ebb8dd6eac",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "479d6970-6516-50f5-9436-bb5b56d58aad"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0025",
|
||||
"from": "NK-WP-0025",
|
||||
"target": "NK-WP-0024",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "2412a251-d6b5-5f05-8082-3eb7697c51dc",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "635a73d4-b3cb-5c38-af22-56a6a66beb0e",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0016",
|
||||
"from": "NK-WP-0016",
|
||||
"target": "NK-WP-0015",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "2d592e18-e63d-4856-97a1-f8c3e019e150",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "343e035d-41e1-4fc4-b209-6872e4a5fdc8",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0006",
|
||||
"from": "NK-WP-0006",
|
||||
"target": "NK-WP-0005",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "2eb8a5e0-4e33-4ed3-8996-a2eec3aad862",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "75bc472b-cc0a-48f2-afb6-62b896f7cc19",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0006",
|
||||
"from": "NK-WP-0006",
|
||||
"target": "NK-WP-0004",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "2eb8a5e0-4e33-4ed3-8996-a2eec3aad862",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "d9cf7c4b-886b-4cd1-ad7b-99c4e1929c9e",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0013",
|
||||
"from": "NK-WP-0013",
|
||||
"target": "NK-WP-0006",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "32a54d8e-8633-42a6-8ec1-104842c581c1",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "2eb8a5e0-4e33-4ed3-8996-a2eec3aad862",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0015",
|
||||
"from": "NK-WP-0015",
|
||||
"target": "NK-WP-0014",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "343e035d-41e1-4fc4-b209-6872e4a5fdc8",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "b9bf56bc-7ef6-43eb-badc-fa0f4896c63c",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NET-WP-0017",
|
||||
"from": "NET-WP-0017",
|
||||
"target": "NET-WP-0016",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "385de708-fd59-4bab-a4f4-28c1c476b3ea",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "16069174-6698-4855-ad9e-5092c8571f38",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NET-WP-0017",
|
||||
"from": "NET-WP-0017",
|
||||
"target": "NET-WP-0015",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "385de708-fd59-4bab-a4f4-28c1c476b3ea",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "6b9c25e4-1008-429a-8de6-54361872c0dd",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0007",
|
||||
"from": "NK-WP-0007",
|
||||
"target": "NK-WP-0006",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "3cbc81ec-7ad5-46cf-a4a0-fc5fe9873695",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "2eb8a5e0-4e33-4ed3-8996-a2eec3aad862",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0007",
|
||||
"from": "NK-WP-0007",
|
||||
"target": "NK-WP-0005",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "3cbc81ec-7ad5-46cf-a4a0-fc5fe9873695",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "75bc472b-cc0a-48f2-afb6-62b896f7cc19",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0007",
|
||||
"from": "NK-WP-0007",
|
||||
"target": "NK-WP-0004",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "3cbc81ec-7ad5-46cf-a4a0-fc5fe9873695",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "d9cf7c4b-886b-4cd1-ad7b-99c4e1929c9e",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0024",
|
||||
"from": "NK-WP-0024",
|
||||
"target": "NK-WP-0023",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "635a73d4-b3cb-5c38-af22-56a6a66beb0e",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "fdb3deee-06c3-5d12-91ce-9c50b2ac0618",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NET-WP-0015",
|
||||
"from": "NET-WP-0015",
|
||||
"target": "NK-WP-0006",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "6b9c25e4-1008-429a-8de6-54361872c0dd",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "2eb8a5e0-4e33-4ed3-8996-a2eec3aad862",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NET-WP-0015",
|
||||
"from": "NET-WP-0015",
|
||||
"target": "NK-WP-0012",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "6b9c25e4-1008-429a-8de6-54361872c0dd",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "9b8e4afc-eb71-47d9-8750-799a082b320a",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0018",
|
||||
"from": "NK-WP-0018",
|
||||
"target": "NK-WP-0017",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "6f75035a-e056-4eab-8fdb-00a18bacdf87",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "08398d26-cadf-44bc-97ee-67da790040e6",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0018",
|
||||
"from": "NK-WP-0018",
|
||||
"target": "NK-WP-0016",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "6f75035a-e056-4eab-8fdb-00a18bacdf87",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "2d592e18-e63d-4856-97a1-f8c3e019e150",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0005",
|
||||
"from": "NK-WP-0005",
|
||||
"target": "NK-WP-0004",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "75bc472b-cc0a-48f2-afb6-62b896f7cc19",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "d9cf7c4b-886b-4cd1-ad7b-99c4e1929c9e",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NET-WP-0019",
|
||||
"from": "NET-WP-0019",
|
||||
"target": "NET-WP-0017",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "75d388b6-7ec1-4e1b-8c87-6ff44f953210",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "385de708-fd59-4bab-a4f4-28c1c476b3ea",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NET-WP-0019",
|
||||
"from": "NET-WP-0019",
|
||||
"target": "NET-WP-0018",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "75d388b6-7ec1-4e1b-8c87-6ff44f953210",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "800f9f16-bc44-4bbf-a771-58a630a3b698",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NET-WP-0018",
|
||||
"from": "NET-WP-0018",
|
||||
"target": "NET-WP-0017",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "800f9f16-bc44-4bbf-a771-58a630a3b698",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "385de708-fd59-4bab-a4f4-28c1c476b3ea",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NET-WP-0018",
|
||||
"from": "NET-WP-0018",
|
||||
"target": "NET-WP-0015",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "800f9f16-bc44-4bbf-a771-58a630a3b698",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "6b9c25e4-1008-429a-8de6-54361872c0dd",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0027",
|
||||
"from": "NK-WP-0027-T03",
|
||||
"target": "NK-WP-0027-T02",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "965ad365-6b81-50a1-a2a3-2d0c1fcce0b4",
|
||||
"from_task_id": "e3f0bb0f-0c85-5cb9-a5ab-75f668cd3447",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "5b35b646-a525-55da-852a-6005613d42ea"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0012",
|
||||
"from": "NK-WP-0012",
|
||||
"target": "NK-WP-0006",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "9b8e4afc-eb71-47d9-8750-799a082b320a",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "2eb8a5e0-4e33-4ed3-8996-a2eec3aad862",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0014",
|
||||
"from": "NK-WP-0014",
|
||||
"target": "NK-WP-0013",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "b9bf56bc-7ef6-43eb-badc-fa0f4896c63c",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "32a54d8e-8633-42a6-8ec1-104842c581c1",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0014",
|
||||
"from": "NK-WP-0014",
|
||||
"target": "NK-WP-0012",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "b9bf56bc-7ef6-43eb-badc-fa0f4896c63c",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "9b8e4afc-eb71-47d9-8750-799a082b320a",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0019",
|
||||
"from": "NK-WP-0019",
|
||||
"target": "NK-WP-0018",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "d2daa8b4-8ecf-4377-b382-492e653735f7",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "6f75035a-e056-4eab-8fdb-00a18bacdf87",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0009",
|
||||
"from": "NK-WP-0009",
|
||||
"target": "NK-WP-0008",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "d4d02dbf-3974-502d-8b87-b776fc63e17e",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "053c6d96-9396-40c9-a2e5-c36531e7810d",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0022",
|
||||
"from": "NK-WP-0022",
|
||||
"target": "NK-WP-0023",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "d76ddccc-00c8-548a-b141-2cd660fa38da",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "fdb3deee-06c3-5d12-91ce-9c50b2ac0618",
|
||||
"to_task_id": null
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0048",
|
||||
"from": "NK-WP-0048-T07",
|
||||
"target": "NK-WP-0048-T06",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "e31f3f9d-0748-5137-b0a3-7b3ca46a66eb",
|
||||
"from_task_id": "c3c9c3ae-4f23-5ba7-9e6f-e63bcf29b9f7",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "d9b26bcf-a7c6-59a2-92a0-f913d76a203c"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0048",
|
||||
"from": "NK-WP-0048-T06",
|
||||
"target": "NK-WP-0048-T09",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "e31f3f9d-0748-5137-b0a3-7b3ca46a66eb",
|
||||
"from_task_id": "d9b26bcf-a7c6-59a2-92a0-f913d76a203c",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "0ee12dfc-8260-5038-bd39-cc7fb4113be0"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0048",
|
||||
"from": "NK-WP-0048-T06",
|
||||
"target": "NK-WP-0048-T15",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "e31f3f9d-0748-5137-b0a3-7b3ca46a66eb",
|
||||
"from_task_id": "d9b26bcf-a7c6-59a2-92a0-f913d76a203c",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "1b825705-4848-5edc-832f-b1622cd9bdb7"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0048",
|
||||
"from": "NK-WP-0048-T06",
|
||||
"target": "NK-WP-0048-T16",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "e31f3f9d-0748-5137-b0a3-7b3ca46a66eb",
|
||||
"from_task_id": "d9b26bcf-a7c6-59a2-92a0-f913d76a203c",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "200bf500-5084-5ae7-be26-3033fe1f296e"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0048",
|
||||
"from": "NK-WP-0048-T06",
|
||||
"target": "NK-WP-0048-T05",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "e31f3f9d-0748-5137-b0a3-7b3ca46a66eb",
|
||||
"from_task_id": "d9b26bcf-a7c6-59a2-92a0-f913d76a203c",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "3d987d3d-0797-538b-86e4-51185a327ae2"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0048",
|
||||
"from": "NK-WP-0048-T06",
|
||||
"target": "MASON-WP-0010-T03",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "e31f3f9d-0748-5137-b0a3-7b3ca46a66eb",
|
||||
"from_task_id": "d9b26bcf-a7c6-59a2-92a0-f913d76a203c",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "56cea6be-c613-586c-80cd-125340b374da"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0048",
|
||||
"from": "NK-WP-0048-T06",
|
||||
"target": "NK-WP-0048-T12",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "e31f3f9d-0748-5137-b0a3-7b3ca46a66eb",
|
||||
"from_task_id": "d9b26bcf-a7c6-59a2-92a0-f913d76a203c",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "7ce4eee3-cd47-55a9-bfa5-4f1835d4d6fd"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0048",
|
||||
"from": "NK-WP-0048-T06",
|
||||
"target": "NK-WP-0048-T20",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "e31f3f9d-0748-5137-b0a3-7b3ca46a66eb",
|
||||
"from_task_id": "d9b26bcf-a7c6-59a2-92a0-f913d76a203c",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "863fcbdb-e246-51ba-87ca-a2f44d01d6f8"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0048",
|
||||
"from": "NK-WP-0048-T06",
|
||||
"target": "NK-WP-0048-T17",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "e31f3f9d-0748-5137-b0a3-7b3ca46a66eb",
|
||||
"from_task_id": "d9b26bcf-a7c6-59a2-92a0-f913d76a203c",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "8c3e4baa-a218-5996-af9e-fe1153a46dac"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0048",
|
||||
"from": "NK-WP-0048-T06",
|
||||
"target": "NK-WP-0048-T08",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "e31f3f9d-0748-5137-b0a3-7b3ca46a66eb",
|
||||
"from_task_id": "d9b26bcf-a7c6-59a2-92a0-f913d76a203c",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "8e519082-dc8b-5e46-b660-03d03e55dcf6"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0048",
|
||||
"from": "NK-WP-0048-T06",
|
||||
"target": "NK-WP-0048-T18",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "e31f3f9d-0748-5137-b0a3-7b3ca46a66eb",
|
||||
"from_task_id": "d9b26bcf-a7c6-59a2-92a0-f913d76a203c",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "9c45da71-fb4c-5f20-9065-90f448f37c64"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0048",
|
||||
"from": "NK-WP-0048-T06",
|
||||
"target": "NK-WP-0048-T13",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "e31f3f9d-0748-5137-b0a3-7b3ca46a66eb",
|
||||
"from_task_id": "d9b26bcf-a7c6-59a2-92a0-f913d76a203c",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "b264c10b-565c-5d29-b788-03cf5fbd2883"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0048",
|
||||
"from": "NK-WP-0048-T06",
|
||||
"target": "WARDEN-WP-0044-T03",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "e31f3f9d-0748-5137-b0a3-7b3ca46a66eb",
|
||||
"from_task_id": "d9b26bcf-a7c6-59a2-92a0-f913d76a203c",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "bcbf6c91-2c04-5c16-ae8c-5d6c06fd6b89"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0048",
|
||||
"from": "NK-WP-0048-T06",
|
||||
"target": "NK-WP-0048-T14",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "e31f3f9d-0748-5137-b0a3-7b3ca46a66eb",
|
||||
"from_task_id": "d9b26bcf-a7c6-59a2-92a0-f913d76a203c",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "fce95440-a25b-5f27-8ef3-a3d182099113"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0048",
|
||||
"from": "NK-WP-0048-T14",
|
||||
"target": "NK-WP-0048-T20",
|
||||
"relationship_type": "starts_after",
|
||||
"from_workplan_id": "e31f3f9d-0748-5137-b0a3-7b3ca46a66eb",
|
||||
"from_task_id": "fce95440-a25b-5f27-8ef3-a3d182099113",
|
||||
"to_workplan_id": null,
|
||||
"to_task_id": "863fcbdb-e246-51ba-87ca-a2f44d01d6f8"
|
||||
},
|
||||
{
|
||||
"workplan": "NK-WP-0010",
|
||||
"from": "NK-WP-0010",
|
||||
"target": "NK-WP-0008",
|
||||
"relationship_type": "blocks",
|
||||
"from_workplan_id": "f4faf8b4-ae57-40cf-a881-6fe66ca6ad74",
|
||||
"from_task_id": null,
|
||||
"to_workplan_id": "053c6d96-9396-40c9-a2e5-c36531e7810d",
|
||||
"to_task_id": null
|
||||
}
|
||||
],
|
||||
"refused": [],
|
||||
"notes": []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
"""Scoped normal owner publication; preserve unrelated index/worktree state."""
|
||||
from pathlib import Path
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import urllib.request
|
||||
import yaml
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
ROOT = Path('/home/worsch/net-kingdom')
|
||||
BASE = HERE.parent
|
||||
EXPECTED_BASE = '70f408ca2389bf3722a91a03832fc6e8587355e5'
|
||||
PLANS = ['workplans/NK-WP-0048-security-case-types.md',
|
||||
'workplans/NK-WP-0049-bootstrap-secret-free-recovery-handoff.md']
|
||||
PATHS = ['tools/bootstrap-recovery/isolated-keycape.py',
|
||||
'tests/test_isolated_keycape_recovery.py',
|
||||
'tests/isolated-keycape-native-fixture-manifest.json', *PLANS]
|
||||
NEW = {'NK-WP-0048-T22', 'NK-WP-0048-T23', 'NK-WP-0049-T38'}
|
||||
PINS = ['86f37add7221e4c73e3f9d878c09a3cc81061627cbf024ed6887d973d929b718',
|
||||
'5f729e077db51dd6b17d00dc3eb71c0e652849f55fe68505a07befa663c91dea',
|
||||
'936ee435be04b27f391391e7dda02def69e153bde3adcce92d569f33f308db2e',
|
||||
'0fdc263a5b23d376a2c6e908e955c91fdaf8121144da59ebc6e5aee8ef727f5e',
|
||||
'e0cd01320b366ab8961a0a52a908edc1524f98b3cfab7382a14fa915da2f60a2']
|
||||
BACKUP = HERE / 'unrelated-backup'
|
||||
sys.path.insert(0, '/home/worsch/repo-manager/src')
|
||||
from repo_manager.identifiers import ensure_missing_work_record_identifiers
|
||||
|
||||
def git(*args):
|
||||
return subprocess.check_output(['git', '-C', str(ROOT), *args], stderr=subprocess.PIPE, timeout=40)
|
||||
|
||||
def sha(raw):
|
||||
return hashlib.sha256(raw).hexdigest()
|
||||
|
||||
def write(name, value):
|
||||
(HERE / name).write_text(json.dumps(value, indent=2) + '\n')
|
||||
|
||||
def tasks(raw):
|
||||
return {t['id']: t for t in (yaml.safe_load(s) for s in re.findall(r'```task\n(.*?)\n```', raw, re.S))}
|
||||
|
||||
def check_old_tasks():
|
||||
for name in PLANS:
|
||||
old = tasks(git('show', EXPECTED_BASE + ':' + name).decode())
|
||||
actual = tasks((ROOT / name).read_text())
|
||||
assert all(actual[k] == v for k, v in old.items()), 'existing task changed'
|
||||
assert set(actual) - set(old) <= NEW
|
||||
assert sum(len(tasks((ROOT / name).read_text())) for name in PLANS) == 61
|
||||
|
||||
def backup():
|
||||
assert not BACKUP.exists()
|
||||
BACKUP.mkdir()
|
||||
originals = {}
|
||||
for name in ['.custodian-brief.md', 'WORK-RECORDS.md']:
|
||||
raw = (ROOT / name).read_bytes()
|
||||
(BACKUP / (name + '.worktree')).write_bytes(raw)
|
||||
originals[name] = git('ls-files', '--stage', '--', name).decode()
|
||||
(BACKUP / 'originals.json').write_text(json.dumps(originals))
|
||||
# The older publication's original user edits must still be intact.
|
||||
old = BASE / 'netkingdom-publication-backup'
|
||||
for name, entry in json.loads((old / 'originals.json').read_text()).items():
|
||||
assert (ROOT / name).read_bytes() == (old / (name + '.worktree')).read_bytes()
|
||||
assert originals[name] == entry
|
||||
|
||||
def preserve(restore=False):
|
||||
for name, entry in json.loads((BACKUP / 'originals.json').read_text()).items():
|
||||
raw = (BACKUP / (name + '.worktree')).read_bytes()
|
||||
if restore:
|
||||
(ROOT / name).write_bytes(raw)
|
||||
mode, oid, stage, path = entry.split()
|
||||
assert stage == '0'
|
||||
git('update-index', '--cacheinfo', mode, oid, path)
|
||||
assert (ROOT / name).read_bytes() == raw
|
||||
assert git('ls-files', '--stage', '--', name).decode() == entry
|
||||
|
||||
def commit():
|
||||
assert git('rev-parse', 'HEAD').decode().strip() == EXPECTED_BASE
|
||||
assert git('ls-remote', 'origin', 'refs/heads/main').decode().split()[0] == EXPECTED_BASE
|
||||
assert all(sha((ROOT / name).read_bytes()) == pin for name, pin in zip(PATHS, PINS))
|
||||
check_old_tasks()
|
||||
preview = ensure_missing_work_record_identifiers(ROOT, execute=False)
|
||||
assert preview['ok'] and set(preview['files_changed']) == set(PLANS)
|
||||
assert {a['record_id'] for a in preview['assignments']} == NEW
|
||||
backup()
|
||||
assigned = ensure_missing_work_record_identifiers(ROOT)
|
||||
assert assigned['ok'] and assigned['assignments'] == preview['assignments']
|
||||
check_old_tasks()
|
||||
files = [{'path': p, 'sha256': sha((ROOT / p).read_bytes())} for p in PATHS]
|
||||
git('add', '--', *PATHS)
|
||||
result = subprocess.run(['git', '-C', str(ROOT), 'commit', '--only', '-m',
|
||||
'fix(recovery): require one original client and refine native owner gates', '--', *PATHS],
|
||||
capture_output=True, text=True, timeout=180)
|
||||
(HERE / 'commit.stdout.txt').write_text(result.stdout)
|
||||
(HERE / 'commit.stderr.txt').write_text(result.stderr)
|
||||
head = git('rev-parse', 'HEAD').decode().strip()
|
||||
write('commit.json', {'exit_code': result.returncode, 'commit': head, 'base': EXPECTED_BASE,
|
||||
'files': files, 'identifier_assignments': assigned, 'native_target_gates_closed': 0})
|
||||
preserve()
|
||||
assert result.returncode == 0, 'normal hook refused; failure retained'
|
||||
assert set(git('diff-tree', '--no-commit-id', '--name-only', '-r', head).decode().splitlines()) == set(PATHS)
|
||||
print(json.dumps({'status': 'committed', 'commit': head, 'paths': len(PATHS)}))
|
||||
|
||||
def sync():
|
||||
head = json.loads((HERE / 'commit.json').read_text())['commit']
|
||||
assert git('rev-parse', 'HEAD').decode().strip() == head
|
||||
try:
|
||||
for label, argv, timeout in [
|
||||
('consistency', ['statehub', 'fix-consistency', '--repo', 'net-kingdom', '--json'], 300),
|
||||
('projection', ['/home/worsch/repo-manager/.venv/bin/rmgr', 'sync', '--path', str(ROOT), '--push'], 180)]:
|
||||
result = subprocess.run(argv, cwd=ROOT, capture_output=True, text=True, timeout=timeout)
|
||||
(HERE / (label + '.json')).write_text(result.stdout)
|
||||
(HERE / (label + '.stderr.txt')).write_text(result.stderr)
|
||||
assert result.returncode == 0, label + ' failed; receipt retained'
|
||||
finally:
|
||||
preserve(restore=True)
|
||||
projection = json.loads((HERE / 'projection.json').read_text())
|
||||
assert projection['status'] == 'applied' and projection['commit'] == head
|
||||
assert projection['receipt']['expected_commit'] == projection['receipt']['derived_commit'] == head
|
||||
assert projection['receipt']['instance_role'] == 'primary'
|
||||
assert projection['receipt']['instance_label'] == 'railiance01'
|
||||
assert git('ls-remote', 'origin', 'refs/heads/main').decode().split()[0] == head
|
||||
print(json.dumps({'status': 'applied', 'commit': head, 'other_work_preserved': True}))
|
||||
|
||||
def verify():
|
||||
commit_receipt = json.loads((HERE / 'commit.json').read_text())
|
||||
head = commit_receipt['commit']
|
||||
assert git('rev-parse', 'HEAD').decode().strip() == head
|
||||
assert git('ls-remote', 'origin', 'refs/heads/main').decode().split()[0] == head
|
||||
for f in commit_receipt['files']:
|
||||
assert sha((ROOT / f['path']).read_bytes()) == f['sha256']
|
||||
assert git('show', head + ':' + f['path']) == (ROOT / f['path']).read_bytes()
|
||||
check_old_tasks()
|
||||
def get(path):
|
||||
return json.load(urllib.request.urlopen('http://127.0.0.1:8000' + path, timeout=30))
|
||||
health = get('/state/health')
|
||||
assert health['instance_role'] == 'primary' and health['instance_label'] == 'railiance01'
|
||||
snapshot = get('/repos/net-kingdom/work-record-projection/snapshot')
|
||||
all_tasks = {t['id']: t for t in snapshot['tasks']}
|
||||
source = {k: v for name in PLANS for k, v in tasks((ROOT / name).read_text()).items()}
|
||||
rows = []
|
||||
for name in PLANS:
|
||||
raw = (ROOT / name).read_text()
|
||||
front = yaml.safe_load(raw.split('---', 2)[1])
|
||||
plan = next(p for p in snapshot['workplans'] if p['id'] == front['state_hub_workstream_id'])
|
||||
assert plan['status'] == front['status'] == 'active'
|
||||
selected = tasks(raw)
|
||||
projected = [t for t in snapshot['tasks'] if t.get('workplan_id', t.get('workstream_id')) == plan['id']]
|
||||
assert len(projected) == len(selected)
|
||||
for task in selected.values():
|
||||
actual = all_tasks[task['state_hub_task_id']]
|
||||
assert actual['record_id'] == task['id'] and actual['status'] == task['status']
|
||||
internal = {(t['state_hub_task_id'], source[d]['state_hub_task_id'], 'starts_after')
|
||||
for t in selected.values() for d in t.get('depends_on', []) if d in source}
|
||||
actual_edges = {(e['from_task_id'], e.get('to_task_id'), e['relationship_type'])
|
||||
for e in snapshot['dependencies'] if e['from_workplan_id'] == plan['id'] and e.get('from_task_id')}
|
||||
assert internal <= actual_edges, 'missing source internal dependency'
|
||||
rows.append({'workplan': front['id'], 'status': plan['status'], 'task_count': len(projected),
|
||||
'tasks': [{'record_id': t['record_id'], 'uuid': t['id'], 'status': t['status']} for t in projected],
|
||||
'internal_dependencies_verified': len(internal)})
|
||||
preserve()
|
||||
write('verified-bindings.json', {'status': 'verified', 'commit': head,
|
||||
'primary': 'primary/railiance01', 'task_bindings': 61, 'old_bindings_preserved': 58,
|
||||
'new_completed_source_deliverables': sorted(NEW), 'rows': rows,
|
||||
'unrelated_index_and_worktree_preserved': True, 'native_target_gates_closed': 0})
|
||||
print(json.dumps({'status': 'verified', 'commit': head, 'task_bindings': 61}))
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('action', choices=['commit', 'sync', 'verify'])
|
||||
action = parser.parse_args().action
|
||||
globals()[action]()
|
||||
|
|
@ -0,0 +1,176 @@
|
|||
"""Scoped normal owner publication; preserve unrelated index/worktree state."""
|
||||
from pathlib import Path
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import urllib.request
|
||||
import yaml
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
ROOT = Path('/home/worsch/net-kingdom')
|
||||
BASE = HERE.parent
|
||||
EXPECTED_BASE = '70f408ca2389bf3722a91a03832fc6e8587355e5'
|
||||
PLANS = ['workplans/NK-WP-0048-security-case-types.md',
|
||||
'workplans/NK-WP-0049-bootstrap-secret-free-recovery-handoff.md']
|
||||
PATHS = ['tools/bootstrap-recovery/isolated-keycape.py',
|
||||
'tests/test_isolated_keycape_recovery.py',
|
||||
'tests/isolated-keycape-native-fixture-manifest.json', *PLANS]
|
||||
NEW = {'NK-WP-0048-T22', 'NK-WP-0048-T23', 'NK-WP-0049-T38'}
|
||||
PINS = ['86f37add7221e4c73e3f9d878c09a3cc81061627cbf024ed6887d973d929b718',
|
||||
'5f729e077db51dd6b17d00dc3eb71c0e652849f55fe68505a07befa663c91dea',
|
||||
'936ee435be04b27f391391e7dda02def69e153bde3adcce92d569f33f308db2e',
|
||||
'0fdc263a5b23d376a2c6e908e955c91fdaf8121144da59ebc6e5aee8ef727f5e',
|
||||
'e0cd01320b366ab8961a0a52a908edc1524f98b3cfab7382a14fa915da2f60a2']
|
||||
BACKUP = HERE / 'unrelated-backup'
|
||||
sys.path.insert(0, '/home/worsch/repo-manager/src')
|
||||
from repo_manager.identifiers import ensure_missing_work_record_identifiers
|
||||
|
||||
def git(*args):
|
||||
return subprocess.check_output(['git', '-C', str(ROOT), *args], stderr=subprocess.PIPE, timeout=40)
|
||||
|
||||
def sha(raw):
|
||||
return hashlib.sha256(raw).hexdigest()
|
||||
|
||||
def write(name, value):
|
||||
(HERE / name).write_text(json.dumps(value, indent=2) + '\n')
|
||||
|
||||
def tasks(raw):
|
||||
return {t['id']: t for t in (yaml.safe_load(s) for s in re.findall(r'```task\n(.*?)\n```', raw, re.S))}
|
||||
|
||||
def check_old_tasks():
|
||||
for name in PLANS:
|
||||
old = tasks(git('show', EXPECTED_BASE + ':' + name).decode())
|
||||
actual = tasks((ROOT / name).read_text())
|
||||
assert all(actual[k] == v for k, v in old.items()), 'existing task changed'
|
||||
assert set(actual) - set(old) <= NEW
|
||||
assert sum(len(tasks((ROOT / name).read_text())) for name in PLANS) == 61
|
||||
|
||||
def backup():
|
||||
assert not BACKUP.exists()
|
||||
BACKUP.mkdir()
|
||||
originals = {}
|
||||
for name in ['.custodian-brief.md', 'WORK-RECORDS.md']:
|
||||
raw = (ROOT / name).read_bytes()
|
||||
(BACKUP / (name + '.worktree')).write_bytes(raw)
|
||||
originals[name] = git('ls-files', '--stage', '--', name).decode()
|
||||
(BACKUP / 'originals.json').write_text(json.dumps(originals))
|
||||
# The older publication's original user edits must still be intact.
|
||||
old = BASE / 'netkingdom-publication-backup'
|
||||
for name, entry in json.loads((old / 'originals.json').read_text()).items():
|
||||
assert (ROOT / name).read_bytes() == (old / (name + '.worktree')).read_bytes()
|
||||
assert originals[name] == entry
|
||||
|
||||
def preserve(restore=False):
|
||||
for name, entry in json.loads((BACKUP / 'originals.json').read_text()).items():
|
||||
raw = (BACKUP / (name + '.worktree')).read_bytes()
|
||||
if restore:
|
||||
(ROOT / name).write_bytes(raw)
|
||||
mode, oid, stage, path = entry.split()
|
||||
assert stage == '0'
|
||||
git('update-index', '--cacheinfo', mode, oid, path)
|
||||
assert (ROOT / name).read_bytes() == raw
|
||||
assert git('ls-files', '--stage', '--', name).decode() == entry
|
||||
|
||||
def commit():
|
||||
assert git('rev-parse', 'HEAD').decode().strip() == EXPECTED_BASE
|
||||
assert git('ls-remote', 'origin', 'refs/heads/main').decode().split()[0] == EXPECTED_BASE
|
||||
assert all(sha((ROOT / name).read_bytes()) == pin for name, pin in zip(PATHS, PINS))
|
||||
check_old_tasks()
|
||||
preview = ensure_missing_work_record_identifiers(ROOT, execute=False)
|
||||
assert preview['ok'] and set(preview['files_changed']) == set(PLANS)
|
||||
assert {a['record_id'] for a in preview['assignments']} == NEW
|
||||
backup()
|
||||
assigned = ensure_missing_work_record_identifiers(ROOT)
|
||||
assert assigned['ok'] and assigned['assignments'] == preview['assignments']
|
||||
check_old_tasks()
|
||||
files = [{'path': p, 'sha256': sha((ROOT / p).read_bytes())} for p in PATHS]
|
||||
git('add', '--', *PATHS)
|
||||
result = subprocess.run(['git', '-C', str(ROOT), 'commit', '--only', '-m',
|
||||
'fix(recovery): require one original client and refine native owner gates', '--', *PATHS],
|
||||
capture_output=True, text=True, timeout=180)
|
||||
(HERE / 'commit.stdout.txt').write_text(result.stdout)
|
||||
(HERE / 'commit.stderr.txt').write_text(result.stderr)
|
||||
head = git('rev-parse', 'HEAD').decode().strip()
|
||||
write('commit.json', {'exit_code': result.returncode, 'commit': head, 'base': EXPECTED_BASE,
|
||||
'files': files, 'identifier_assignments': assigned, 'native_target_gates_closed': 0})
|
||||
preserve()
|
||||
assert result.returncode == 0, 'normal hook refused; failure retained'
|
||||
assert set(git('diff-tree', '--no-commit-id', '--name-only', '-r', head).decode().splitlines()) == set(PATHS)
|
||||
print(json.dumps({'status': 'committed', 'commit': head, 'paths': len(PATHS)}))
|
||||
|
||||
def sync():
|
||||
head = json.loads((HERE / 'commit.json').read_text())['commit']
|
||||
assert git('rev-parse', 'HEAD').decode().strip() == head
|
||||
try:
|
||||
for label, argv, timeout in [
|
||||
('consistency', ['statehub', 'fix-consistency', '--repo', 'net-kingdom', '--json'], 300),
|
||||
('projection', ['/home/worsch/repo-manager/.venv/bin/rmgr', 'sync', '--path', str(ROOT), '--push'], 180)]:
|
||||
result = subprocess.run(argv, cwd=ROOT, capture_output=True, text=True, timeout=timeout)
|
||||
(HERE / (label + '.json')).write_text(result.stdout)
|
||||
(HERE / (label + '.stderr.txt')).write_text(result.stderr)
|
||||
assert result.returncode == 0, label + ' failed; receipt retained'
|
||||
finally:
|
||||
preserve(restore=True)
|
||||
projection = json.loads((HERE / 'projection.json').read_text())
|
||||
assert projection['status'] == 'applied' and projection['commit'] == head
|
||||
assert projection['receipt']['expected_commit'] == projection['receipt']['derived_commit'] == head
|
||||
assert projection['receipt']['instance_role'] == 'primary'
|
||||
assert projection['receipt']['instance_label'] == 'railiance01'
|
||||
assert git('ls-remote', 'origin', 'refs/heads/main').decode().split()[0] == head
|
||||
print(json.dumps({'status': 'applied', 'commit': head, 'other_work_preserved': True}))
|
||||
|
||||
def verify():
|
||||
commit_receipt = json.loads((HERE / 'commit.json').read_text())
|
||||
head = commit_receipt['commit']
|
||||
assert git('rev-parse', 'HEAD').decode().strip() == head
|
||||
assert git('ls-remote', 'origin', 'refs/heads/main').decode().split()[0] == head
|
||||
for f in commit_receipt['files']:
|
||||
assert sha((ROOT / f['path']).read_bytes()) == f['sha256']
|
||||
assert git('show', head + ':' + f['path']) == (ROOT / f['path']).read_bytes()
|
||||
check_old_tasks()
|
||||
def get(path):
|
||||
return json.load(urllib.request.urlopen('http://127.0.0.1:8000' + path, timeout=30))
|
||||
health = get('/state/health')
|
||||
assert health['instance_role'] == 'primary' and health['instance_label'] == 'railiance01'
|
||||
snapshot = get('/repos/net-kingdom/work-record-projection/snapshot')
|
||||
all_tasks = {t['id']: t for t in snapshot['tasks']}
|
||||
source = {k: v for name in PLANS for k, v in tasks((ROOT / name).read_text()).items()}
|
||||
rows = []
|
||||
for name in PLANS:
|
||||
raw = (ROOT / name).read_text()
|
||||
front = yaml.safe_load(raw.split('---', 2)[1])
|
||||
plan = next(p for p in snapshot['workplans'] if p['id'] == front['state_hub_workstream_id'])
|
||||
assert plan['status'] == front['status'] == 'active'
|
||||
selected = tasks(raw)
|
||||
projected = [t for t in snapshot['tasks'] if t.get('workplan_id', t.get('workstream_id')) == plan['id']]
|
||||
assert len(projected) == len(selected)
|
||||
for task in selected.values():
|
||||
actual = all_tasks[task['state_hub_task_id']]
|
||||
assert actual['record_id'] == task['id'] and actual['status'] == task['status']
|
||||
internal = {(t['state_hub_task_id'], source[d]['state_hub_task_id'], 'starts_after')
|
||||
for t in selected.values() if t['status'] not in {'done', 'cancel'}
|
||||
for d in t.get('depends_on', []) if d in source}
|
||||
historical = [(t['id'], d) for t in selected.values() if t['status'] in {'done', 'cancel'}
|
||||
for d in t.get('depends_on', []) if d in source]
|
||||
actual_edges = {(e['from_task_id'], e.get('to_task_id'), e['relationship_type'])
|
||||
for e in snapshot['dependencies'] if e['from_workplan_id'] == plan['id'] and e.get('from_task_id')}
|
||||
assert internal <= actual_edges, 'missing source internal dependency'
|
||||
rows.append({'workplan': front['id'], 'status': plan['status'], 'task_count': len(projected),
|
||||
'tasks': [{'record_id': t['record_id'], 'uuid': t['id'], 'status': t['status']} for t in projected],
|
||||
'active_internal_dependencies_verified': len(internal),
|
||||
'historical_source_dependency_declarations': len(historical)})
|
||||
preserve()
|
||||
write('verified-bindings.json', {'status': 'verified', 'commit': head,
|
||||
'primary': 'primary/railiance01', 'task_bindings': 61, 'old_bindings_preserved': 58,
|
||||
'new_completed_source_deliverables': sorted(NEW), 'rows': rows,
|
||||
'unrelated_index_and_worktree_preserved': True, 'native_target_gates_closed': 0})
|
||||
print(json.dumps({'status': 'verified', 'commit': head, 'task_bindings': 61}))
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('action', choices=['commit', 'sync', 'verify'])
|
||||
action = parser.parse_args().action
|
||||
globals()[action]()
|
||||
Loading…
Add table
Add a link
Reference in a new issue